__LINE__
为什么根据在类似函数的宏还是常规函数中使用它来进行评估?
例如:
#include<stdio.h>
#define A() printf("%d\n",__LINE__);
int main(void) {
/* 6 */ A();
/* 7 */ A(
/* 8 */ );
/* 9 */ printf("%d\n",__LINE__
/* 10 */ );
}
我希望得到:
6
7
9
但是相反,我们得到了(使用clang-1000.10.44.4):
6
8
9
请注意,在类似于函数的宏中,如何分散到第7和8行,而不是第一行,而是最后占用的行。
GCC的文档提供了详细信息:https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
我为什么要关心?我正在编写一个解析器,该解析器需要以与A
将返回的内容对齐的方式来查找宏__LINE__
的所有实例的行号。由于需要解析可能转义的参数,因此很难找到宏用法的 last 行,而不是 first 。
答案 0 :(得分:9)
C实现在看到结束A()
之前不会替换)
宏。 )
出现在第8行,因此是发生宏替换的地方。
__LINE__
的宏替换方面的详细信息未由C标准明确指定。您可能不应在此依赖特定的行为。当然C实现不能替换A()
宏,因为它只读到第7行,因为它尚不知道会发生什么。一旦看到结束)
,那么当它替换宏时,它可能会考虑替换令牌出现在第7行或第8行或某种混合上-C标准对此并不专门;此时,行号在很大程度上与C语义无关,并且__LINE__
宏在很大程度上方便了调试和其他开发工作,而不是生产程序的功能(尽管它们可能有一些用途)。>
在printf
中,C实现在看到行尾时便识别出__LINE__
宏。 (实际上,解析更复杂;输入已被标记化,但是效果是在检查行尾字符时可以识别__LINE__
标记。)它位于第9行,因此被替换了由9
。它是printf
的参数这一事实是无关紧要的。 C实现没有printf
进程来替换第9行上的__LINE__
令牌;他们不会互动。