我最近发现,如果文件结尾为.i或.ii,gcc会跳过预处理,并决定尝试一下。编译不包含stdio.h的hello world程序:
gcc -Wall file.c; # compiles with preprocessor, implicit declaration of puts
gcc -Wall file.i; # compiles without preprocessor, implicit declaration of puts
没有预处理器指令,我无法包含stdio.h,但我记得gcc的-include标志可用于“强制包含”标头。它导致了以下测试:
gcc -Wall -include stdio.h file.c; # no warnings, "hello world". hooray
gcc -Wall -include stdio.h file.i; # implicit declaration of puts WAIT WHAT?!
我发现奇怪的是,如果不经过预处理就编译文件,gcc为何不包含stdio.h。更奇怪的是,如何不发出警告; -include stdio.h
没有明显的效果,这充其量是对gcc的错误使用。
为什么不起作用?
GCC版本6.3.0。
答案 0 :(得分:1)
-include
列在Preprocessor Options下:
3.12控制预处理器的选项
这些选项控制C预处理程序,该处理器在实际编译之前在每个C源文件上运行。
[...]
-include file
处理 file 就像
#include "file"
出现在主源文件的第一行一样。 [...]
但是,对于.i
个文件,预处理器永远不会运行,因此该选项无效。
GCC通常不会警告无效的选项。您还可以运行gcc -Wall -funsigned-char foo.o
,它甚至不会调用编译器。 -Wall
和-funsigned-char
会被忽略。
您可以将编译视为管道:
.c
)通过预处理器,该预处理器产生... .i
),由生成...的编译器处理。.s
),由产生...的汇编器处理。.o
),由链接程序处理,为您提供... 文件名告诉GCC从哪个阶段开始。
选项可用于告知GCC在哪里停止:
-P
在预处理后停止-S
在编译后停止-c
组装后停止其他选项将传递到管道中的相应阶段。如果那部分流水线永远都不会运行,那就什么也没发生。
答案 1 :(得分:0)
-包括 file
处理 file 就像
#include "file"
出现在主源文件的第一行一样。但是,搜索 file 的第一个目录是预处理程序的工作目录代替,该目录包含主源文件。如果没有找到,则照常在#include "…"
搜索链的其余部分中搜索它。如果提供了多个
-include options
,则文件将按照在命令行中出现的顺序包括在内。
第一个短语
处理文件就像
#include "file"
出现在主源文件的第一行一样。
表示您会期望看到的行为。
如果GCC不应用预处理指令,则它将不包含该文件,因为它不会盲目地将stdio.h
的内容添加到正在编译的文件的开头,因此它的作用就像添加了预处理器的include指令。
答案 2 :(得分:0)
这很有意义。 .i文件已经过预处理,因此没有预处理步骤,因此没有包含。
对已预处理的文件进行操作是一个非常高级的主题,因此也许他们只是假设任何这样做的人都知道自己在做什么。
或者也许只是疏忽,您应该得到警告。