GCC 9 最近__LINE__
在某些情况下改变了指令的行为。下面的程序说明了这种变化:
#include <stdio.h>
#define expand() __LINE__
int main() {
printf("%d\n",expand(
));
return 0;
}
因为宏expand()
(扩展为__LINE__
)跨越多行,GCC 最高 8.3(和 Clang 最高 8.0)考虑扩展的最后一行的编号,打印5
。但 GCC 9 考虑第一行,并打印 4。
(Godbolt 链接:https ://godbolt.org/z/3Nk2al )
C11 标准对 的确切行为不是很精确__LINE__
,除了:
6.10.8 预定义的宏名称
以下小节中列出的预定义宏的值(
__FILE__
和除外__LINE__
)在整个翻译单元中保持不变。(...)
6.8.10.1 强制宏
以下宏名称应由实现定义:
(...)
__LINE__
当前源代码行(一个整数常量)的假定行号(在当前源文件中)。
我假设这意味着确切的值是实现定义的,因此不能期望它的值在不同的编译器版本或不同的编译器中保持不变。或者在标准的其他地方是否有一些关于这种效果的论据?
例如,是否有人会争辩说,只要源本身没有改变,当前源行的假定行号就应该是稳定的?