为什么不将__if_exists与局部变量一起使用?

时间:2012-08-17 16:50:24

标签: c++ visual-c++

特定于Microsoft的__if_exists语句的MSDN documentation表示以下内容(重点已添加):

  

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

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

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

编辑:有些人很好奇我为什么要这样做,所以这里有一个解释。 我意识到这是一个肮脏的黑客,所以除非你有一个更好的方法来做到这一点的好建议,请不要指出它是严重的。考虑到代码库的大小,这是我们能够找到的最不完整的选择。

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

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

2 个答案:

答案 0 :(得分:2)

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

我也没有看到为局部变量执行此操作的原因,您在特定范围内,您知道所有内容,为什么要测试局部变量是否存在?

答案 1 :(得分:1)

__if_exists是Visual C ++中的dirty old 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.
}