预定义宏 __FILE__、__LINE__、__func__ 和 stringify(#) 如何工作?

3
如果我的编译器支持这些预定义宏(__FILE__,__LINE__,__func__),那么我就可以安全地使用它们,并假设它总是能正确报告文件和行,参考:C++中 __FILE__, __LINE__ 和 __FUNCTION__ 的用法
我还了解到,变量名、行号等与执行的汇编代码(从.cpp代码生成的实际.exe文件)无关。如果确实如此,那么在代码中使用这些宏时它们是如何工作的呢?在汇编代码中,__LINE__宏表示什么?当遇到__LINE__宏时,.exe文件如何知晓原 .cpp源文件的正确行数?
2个回答

9

LINE宏在汇编代码中如何表示?

它并不是。这些是预处理器宏。一旦预处理器运行,它们将被替换为文字。

例如,如果您有以下代码:

void foo() {
    printf("%d", __LINE__);
}

预处理器将把它转换成这样:
void foo() {
    printf("%d", 2);
}

所以预处理器会检查每个宏的使用情况,并将其替换为数字? - Hatted Rooster
@JameyD 预处理器会对所有宏进行展开 - Some programmer dude

2

1)像__FILE____LINE__这样的“宏”是由编译系统的"预处理器"扩展的。在编译器实际看到源代码之前,源文本会被修改。

2)对于内置宏如“__LINE__”,这同样适用。对于任何你创建的宏,都适用#define语句。

3)像“行号”和“函数名”这样的东西对于调试器非常重要。调试信息是由编译器本身生成的(而不是预处理器)。它与宏扩展或汇编代码生成有关,但不同。

调试信息通常直接保存在可执行文件中(以及汇编指令、字符串字面量等)作为“元数据”。

你可以在这里阅读更多信息:"调试器的工作原理"

补充:

与调试器元数据(上文)类似,func也是类似但不同的。

来自C99标准:

6.4.2.2 预定义标识符

语义:

  1. 标识符__func__应被翻译器隐式声明,就好像在每个函数定义的左花括号后面立即出现了声明

    static const char __func__[] = "function-name";

其中function-name是词法封闭函数的名称。

  1. 这个名称被编码,就好像隐式声明已经写成源字符集然后按照第5个翻译阶段所示转换为执行字符集。

  2. 例子

    #include <stdio.h> void myfunc(void) { printf("%s\n", __func__); /* ... */ }

每次调用函数时,它都会将以下内容打印到标准输出流中:

myfunc

在许多C编译器中,您也会看到__FUNCTION__,但它从未成为标准。

您可以在此处阅读更多内容:

C++中__FILE__,__LINE__和__FUNCTION__的用法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接