__LINE__在传递给类函数宏的lambda中进行了不一致的评估

时间:2013-07-30 19:05:34

标签: c++ c++11

给出以下代码:

1.  #include <iostream>
2.  #define CALL_FUNC(f) f();
3.
4.  int main()
5.  {
6.    CALL_FUNC([](){
7.      std::cout << "I'm on line " << __LINE__ << std::endl;
8.    });
9.    return 0;
10. }

当我在Visual Studio 2012和g ++ 4.7.3中编译它时,我得到输出“我在第8行”。

当我在clang中编译它时,我得到输出“我在第7行”,这是我的预期。

有谁知道这些是正确的行为?有没有办法在VS和g ++中获得所需的行为,同时仍然有一个CALL_FUNC宏?

2 个答案:

答案 0 :(得分:3)

标准未指定宏扩展与__LINE__预定义宏之间的交互。特别是跨越多行并包含__LINE__标记的宏调用在不同的预处理器上表现出不同的行为。当扩展的宏参数的一部分时,一些将给它包含封闭的宏头名称的行号(6),一些是右括号(8)和一些__LINE__令牌行(7)。这取决于所使用的算法,并且有几个是有效且符合标准的。

这可以证明如下:

#define F(x) x
F(
__LINE__
)

一些预处理器将输出2,大约3和大约4。

答案 1 :(得分:2)

快速测试似乎表明,如果你将});向上移动一行就可以了:

std::cout << "I'm on line " << __LINE__ << std::endl;});

gcc和msvc似乎认为它在下一行,因为下一行有});。 (另外,你有一个额外的分号BTW)。