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

How do predefined macro's __FILE__, __LINE__, __func__ ,stringify(#) work?

本文关键字:工作 何工作 stringify FILE LINE func 预定义      更新时间:2023-10-16

如果我的编译器支持这些预定义的宏(__FILE__, __LINE__, __func__),那么我可以安全地使用它们,并假设它总是根据c++中的__FILE__, __LINE__和__FUNCTION__用法报告正确的文件和行

我还读到变量名,行号等与执行的汇编端代码(从。cpp代码产生的实际。exe文件)无关,如果是这种情况,那么这些宏在代码中使用时如何工作?__LINE__宏如何在汇编代码中表示?当遇到__LINE__宏时,.exe文件如何知道原始。cpp源的正确行号?

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

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

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

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

预处理器会把它变成这样:

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

1)__FILE____LINE__等"宏"由编译系统的"预处理器"进行扩展。源文本在编译器自己实际看到它之前被修改。

2)对于像"__LINE__"这样的内置宏来说,这是正确的。对于使用#define语句创建的任何宏都是一样的。

3)像"行号"answers"函数名"这样的东西对调试器很重要。调试信息是由编译器本身(而不是预处理器)生成的。它与宏展开或汇编代码生成相关,但又不同。

调试信息通常作为"元数据"直接保存在可执行文件中(连同汇编指令、字符串文字等)。

你可以在这里阅读更多:"调试器是如何工作的"

附录:

与上面的调试器元数据类似,func与之相似,但又有所不同。

来自C99标准:

6.4.2.2预定义的标识符

语义:

  1. 标识符__func__应由译者隐式声明,就像在每个函数定义的左大括号后面紧接声明

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

出现

,其中function-name是包含词法的函数的名称。

  • 这个名称被编码,就好像隐式声明已经写在源字符集中,然后翻译成执行字符集,如翻译阶段5所示。

  • 的例子考虑代码片段

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

  • 每次调用该函数时,它将输出到标准输出流:

    myfunc

    您也会在许多C编译器中看到__FUNCTION__,但它从来不是标准的。

    你可以在这里阅读更多内容:

    __FILE__、__LINE__ __FUNCTION__在c++中使用