C预处理器默认添加

C preprocessor default additions

使用以下没有导入的存根程序:

int main(void) {
    return 0;
}

运行 上面的 cpp 给我:

$ cpp main.c

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"


int main(void) {
    return 0;
}

我理解它添加 # 1 "main.c" 意思是 #line 1 "main.c" 或“这是给定 main.c 程序的第 1 行。我很想知道 cpp 行。例如,此段:

# 1 "main.c"           <-- why necessary if we have this after the last line and re-defined?
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2

CPP 命令及其输出

当您使用 cpp 命令时,C 预处理器将产生一个 文本 输出,不同于在编译器中使用时,它只会将一些生成的二进制标记传递给编译器本身。

因此,您正在阅读的文本输出很像“调试”或“日志记录”(如果您愿意,也可以是“讲故事”)session预处理器在做什么以及如何做。它基本上会告诉您它是如何扩展找到的宏的。

因此,正如您已经发现的那样,预处理器正在输出行号信息和源文件名,格式如下:

# linenum filename {flags}

称为linemarker,字面意思是:

This line was found in the file named filename at line linenum

如果指定了任何标志,它们的范围可以从 1 到 4,含义如下:

  • 1 -> 开始一个新文件。
  • 2 -> 包含另一个文件后,返回到上一个文件。
  • 3 -> 本文内容取自系统header,所以一些警告被抑制了。
  • 4 -> 将文本内容包装到 extern "C" 块中

让我们一一分析这些行:

  • # 1 "main.c"

以下行位于 main.cline 1,没有其他标志。所以,这就像说“我开始阅读 main.c 的第 1 行”

  • # 1 "<built-in>"

我现在要读一个built-in C pre-procssor指令。请注意这些是如何显示为 <System Header>,但这是虚构的。因此,这一行设置了一个标准的预定义宏,如 _LINUX_ 或 __cplusplus.

阅读更多关于那些 here

额外提示: 运行 cpp -dM main.c 查看所有预定义的宏。

  • # 1 "<command-line>"

我现在要阅读 command-line 选项,其中一个由 -D 标志设置,例如 -DTEST=0,甚至 command-line 未定义,如-UTEST。这些再次从预处理器中呈现为虚构的系统 header 文件。

阅读有关预处理器选项的更多信息here

  • # 31 "<command-line>"

在第 31 行,我正在读取另一个来自 command-line 的宏。 (注意这些是按照找到的顺序设置的)

  • # 1 "/usr/include/stdc-predef.h" 1 3 4

我将阅读位于 /usr/include/stdc-predef.h 的 pre-defined 宏文件,确保此 header 将像系统文件 header 一样包含在内,并且它包含的符号被视为 C 符号。

  • # 32 "<command-line>" 2

我正在恢复阅读command-line《pseudo-header》,我会看完的

  • # 1 "main.c"

我现在继续阅读main.c