gpt4 book ai didi

c - 在宏中使用时 __LINE__ 的行为

转载 作者:太空狗 更新时间:2023-10-29 16:44:44 26 4
gpt4 key购买 nike

为什么 __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__ 将返回的内容对齐。由于需要解析可能转义的参数,因此很难找到宏用法的最后行而不是第一行

最佳答案

C 实现在看到结束 ) 之前不会替换 A() 宏。 ) 出现在第 8 行,所以这是宏替换发生的地方。

关于宏替换的 __LINE__ 的细节在 C 标准中没有很好地指定。您可能不应该依赖此处的特定行为。当然,C 实现不能替换 A() 宏,因为它只读取了第 7 行,因为它还不知道接下来会发生什么。一旦它看到结束 ),然后,当它替换宏时,它可能认为替换标记出现在第 7 行或第 8 行或某些混合上——C 标准不是特定的对这个;在这一点上,行号在很大程度上与 C 语义无关,__LINE__ 宏在很大程度上是为了调试和其他开发工作的便利,而不是生产程序的功能(尽管它可能对它们有一些用途) .

printf 中,C 实现在看到行尾时立即识别 __LINE__ 宏。 (实际上,解析涉及更多;输入已被标记化,但效果是 __LINE__ 标记在检查行尾字符时被识别。)它在第 9 行,所以它被替换为 9。它是 printf 的参数这一事实无关紧要。 C 实现没有进程 printf 以替换出现在第 9 行的 __LINE__ 标记;他们不互动。

关于c - 在宏中使用时 __LINE__ 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56193082/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com