Reputation: 5301
I recently found out gcc skips preprocessing if file ending is .i or .ii and decided to give it a go. Compiling a hello world program without including stdio.h:
gcc -Wall file.c; # compiles with preprocessor, implicit declaration of puts
gcc -Wall file.i; # compiles without preprocessor, implicit declaration of puts
I can't include stdio.h without a preprocessor directive, but I remember the -include flag to gcc can be used to "force include" headers. It led to following test:
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?!
I find it odd how gcc does not include stdio.h if compiling a file without preprocessing. Even odder how no warning is emitted; the -include stdio.h
has no apparent effect, which is erroneous use of gcc at best.
Why is it not working?
GCC version 6.3.0.
Upvotes: 1
Views: 1584
Reputation: 85757
-include
is listed under Preprocessor Options:
3.12 Options Controlling the Preprocessor
These options control the C preprocessor, which is run on each C source file before actual compilation.
[...]
-include file
Process file as if
#include "file"
appeared as the first line of the primary source file. [...]
However, for .i
files the preprocessor never runs, so the option has no effect.
GCC generally doesn't warn about options that have no effect. You can also run gcc -Wall -funsigned-char foo.o
, which doesn't even invoke the compiler. -Wall
and -funsigned-char
are simply ignored.
You can think of compilation as a pipeline:
.c
) passes through the preprocessor, which produces ....i
), which is processed by the compiler producing ....s
), which is processed by the assembler producing ....o
), which is processed by the linker, giving you ...The file name tells GCC which stage to start from.
Options can be used to tell GCC where to stop:
-P
stops after preprocessing-S
stops after compilation-c
stops after assemblingOther options are passed to the corresponding stage in the pipeline. If that part of the pipeline never runs, nothing happens.
Upvotes: 1
Reputation: 5265
From the GCC documentation:
-include file
Process file as if
#include "file"
appeared as the first line of the primary source file. However, the first directory searched for file is the preprocessor’s working directory instead of the directory containing the main source file. If not found there, it is searched for in the remainder of the#include "…"
search chain as normal.If multiple
-include options
are given, the files are included in the order they appear on the command line.
That first phrase
Process file as if
#include "file"
appeared as the first line of the primary source file.
indicates that one would expect the behaviour you see.
If GCC doesn't apply preprocessing directives, it won't include that file, because it doesn't blindly add the contents of stdio.h
to the front of the file being compiled, it acts as if it added the preprocessor include directive.
Upvotes: 0
Reputation: 43188
It makes sense. .i files have already been preprocessed, so there is no preprocess step so there is no include.
Operating on already preprocessed files is an extremely advanced topic so perhaps they just assumed anybody doing it knows what they're doing.
Or maybe it's just an oversight and you should get a warning.
Upvotes: 0