特定于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
是有效的。
正如我上面所说,我知道这是一个肮脏的黑客,所以请不要告诉我它有多难看,除非你对如何做得更好有好的想法。
答案 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.
}