1

Microsoft 特定声明的MSDN 文档说明了以下内容(添加了重点):__if_exists

将 __if_exists 语句应用于类内部或外部的标识符。不要将 __if_exists 语句应用于局部变量

不幸的是,没有解释为什么不应该将它应用于局部变量。它编译得很好并且具有预期的效果,所以我想知道是否有人知道他们为什么说不这样做。是正确性问题、可维护性问题还是其他问题?

我意识到这是 Microsoft 特有的功能,不可移植,但为了争论,我们假设有充分的理由使用它。

编辑:有些人很好奇我为什么要这样做,所以这里有一个解释。我意识到这是一个肮脏的黑客,所以除非你有一个更好的方法来做它的好建议,否则请不要费心指出它很恶心。考虑到代码库的庞大规模,这是我们能找到的最便宜的替代方案。

我们有大量遗留代码(数百万行),它们使用 Microsoft 特定的__FUNCTION__宏作为错误日志记录包的一部分。该代码的很大一部分现在包装在 lambda 函数中,以便我们可以捕获结构化异常(使用__try/ __except)并仍然使用不可缠绕的对象。在那些 lambda 函数中,__FUNCTION__计算出一些无用的东西,比如`anonymous-namespace'::<lambda23>::operator(),这对任何东西都没有用。我们的解决方法是定义类似 new__FUNCTION__的宏,该宏使用__if_exists. 由于宏的工作方式,我们可以轻松切换到新的__FUNCTION__替换并轻松定义备用名称变量,而无需更改大量代码,因此考虑到限制,这是一个相当干净的解决方案。也就是说,当然,假设使用__if_exists这种方式是有效的。

正如我上面所说,我知道这是一个肮脏的黑客,所以请不要告诉我它有多丑陋,除非你对如何做得更好有好的想法。

4

2 回答 2

3

我不确定,但一种猜测是局部变量可能会被编译器优化掉,当然也可能不是,这使得 __if_exists 测试不可靠。

而且我也看不出对局部变量执行此操作的原因,您处于特定范围内,您什么都知道,为什么要测试局部变量是否存在?

于 2012-08-17T16:58:14.323 回答
1

__if_exists是 Visual C++ 中的一个肮脏的旧 hack,具有严重的实现限制,因为它仅适用于 ATL。

局部变量是特殊的,因为你可以有两个同名的局部变量:

void foo()
{ 
  int i = 1;
  {
    int i = 2;
  }
}

这意味着编译器内部有一个更复杂的数据结构来跟踪它们。__if_exists必须进行名称查找,这对于像这样的某些类型的嵌套范围可能不正确。

另一个历史案例是,在 Visual C++ 中,for范围不正确:

void foo()
{ 
  for (int i = 1; false; ) { }
  __if_exists(i) // What do you expect? VC++ let i escape.
}
于 2020-07-14T11:18:14.400 回答