当预处理器处理预处理器行时会发生什么? - '.i'文件

时间:2017-01-30 09:43:09

标签: c gcc c-preprocessor

我正在使用 Gcc 的Gnu cc编译器来编译我的C程序。考虑一个程序,

#include <stdio.h>
int main(){
  return 0;
}

现在,当我使用

预处理上述代码时
cpp sample.c > sample.i

我在 sample.i 中获得了很多我没有包含的内容。比如,'stdio.h'文件已经过预处理。如果是这样的话,

问题1:

为什么预处理文件中有这么多行?我没有使用任何标准库函数,也没有使用宏。

问题2:

任何人都可以解释当预处理器处理C文件时到底发生了什么。(我在'* .i'文件中得到的内容)

编译器:gcc

操作系统:Ubuntu

由于

4 个答案:

答案 0 :(得分:4)

  

为什么预处理文件中有这么多行?我还没有使用任何标准库函数,也没有使用宏。

预处理只是编译过程的一部分。它或多或少是一个简单的文本替换,在预处理阶段不会涉及更复杂的问题。预处理器不知道或不关心您是否在代码程序中使用了任何标准函数。优化器(作为编译过程的一部分)可能 &#34;除去&#34;不需要的零件。但预处理器并没有做到这一点。 它会对您包含的所有头文件以及头文件中包含的其他头文件进行预处理等。

  

任何人都可以解释预处理器处理C文件时到底发生了什么。(我在&#39; *。我&#39;文件中得到的内容)

预处理涉及很多任务:宏替换,条件编译,字符串化,字符串连接等。 您可以在此处详细了解cpp的详细信息:https://gcc.gnu.org/onlinedocs/cpp/

答案 1 :(得分:3)

预处理程序命令#include "aFile.h"会将aFile.h中的漏洞内容放入您的cpp文件中。而这正是预处理器指令所代表的地方。这就是为什么你可以使用in aFile.h定义的函数。

如果您有兴趣了解有关预处理器的更多信息,可以在cplusplus.com

上获得非常好(且简短)的指导

答案 2 :(得分:3)

预处理器执行文本替换。 #include <stdio.h>的净效果是将#include <stdio.h>行替换为<stdio.h>的内容。

实际上,<stdio.h>包含各种函数的几个声明(例如fprintf()fscanf()),变量声明(例如stdoutstdin),以及一些宏定义(在以后的代码中使用时会导致文本替换)。

预处理器被指定为编译阶段,它将源代码作为输入,根据需要替换文本(例如我所描述的#include,宏扩展等),并输出结果源代码。那个输出是你指向sample.i

的输出

然后将预处理器的输出输入到编译的后期阶段,该阶段实际上理解声明,定义,语句等。

编译的阶段是连续的 - 它们一个接一个地发生,而不是一次发生。因此,编译的后期阶段不会向预处理器提供任何信息。编译的后期阶段是检测是否使用了声明等。但是,由于它无法将此类信息反馈给预处理器(并且预处理器是一个无法使用此类信息的无知程序),预处理器无法知道声明是否未被使用,并将其过滤掉。

答案 3 :(得分:1)

1)您可能不会使用它们,但是您已将它们包含在第1行

#include <stdio.h>

这就是你所看到的来自哪里。尝试删除它以查看差异。

2)预处理器读取您的C文件并处理您声明的所有预处理器指令。所有预处理程序指令都以“#”符号开头。 '#include'将用给定文件的内容替换此行。您还拥有经典的'#ifndef'和'#define'指令。后者等于'if'语句,它允许您仅在定义符号时激活代码的一部分

#ifndef _SOME_SYMBOL_
#define _SOME_SYMBOL_

#ifndef WIN32
 #include <some_file.h>
#else
 #include <some_other_file.h>
#endif

int main() { return 0;}

#endif //endof _SOME_SYMBOL_

#ifndef _SOME_SYMBOL_ 
#define _SOME_SYMBOL_

// this second function is ignored
int main() { return 0;}

#endif //endof _SOME_SYMBOL_

当预处理器读取上述文件时,符号“_SOME_SYMBOL_”未知,因此预处理器将其初始化。接下来,它包含文件是否知道WIN32。通常这种符号通过命令行传递。因此,部分代码会动态激活或停用。

预处理器将输出此

void some_other_function_from_some_other_file(){}

int main() { return 0;}