首页 > 解决方案 > C 预处理器默认添加

问题描述

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

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

标签: cgccc-preprocessor

解决方案


CPP 命令及其输出

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

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

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

# linenum filename {flags}

称为linemarker,字面意思是:

此行是在名为的文件中找到filenamelinenum

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

  • 1 -> 开始一个新文件。
  • 2 -> 包含另一个文件后,返回到前一个文件。
  • 3 -> 此文本的内容取自系统标头,因此会抑制一些警告。
  • 4 -> 将文本内容包装成一个extern "C"

让我们一一分析这些行:

  • # 1 "main.c"

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

  • # 1 "<built-in>"

我现在要阅读一个内置的C 预处理指令。注意这些是如何显示的<System Header>,但如果这是虚构的。因此,这一行设置了一个标准的预定义宏,如 _ LINUX _ 或__cplusplus

在此处阅读有关这些的更多信息

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

  • # 1 "<command-line>"

我现在要阅读一个命令行选项,所以其中一个是由-D标志设置的,比如-DTEST=0,甚至是命令行undefinitions,比如-UTEST. 这些再次从预处理器呈现为虚构的系统头文件。

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

  • # 31 "<command-line>"

在第 31 行,我正在阅读来自命令行的另一个宏。(注意这些是按照它们被发现的顺序设置的)

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

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

  • # 32 "<command-line>" 2

我正在继续阅读命令行“伪标题”,我将完成阅读。

  • # 1 "main.c"

我现在将继续阅读main.c


推荐阅读