I was going through the GCC man page, I found the following line:
file.i
C source code that should not be preprocessed.
I know that
A file.i
file is:
C source code that should not be preprocessed.
Source: man gcc
then search for "\.i
".
Detailed Steps: man gcc
, then press the / key to search, then type in \.i
, then press the Enter key, then press the n key repeatedly until you find it.
What this means is that a .i
file is preprocessed source code, so it already contains:
...as stated by @Sathish in his answer. You'll also notice a ton of special "comments" added by gcc that now begin with the #
character, such as these:
# 1 "main.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "main.c" # 44 "main.c" # 1 "/usr/include/stdio.h" 1 3 4 # 27 "/usr/include/stdio.h" 3 4 # 1 "/usr/include/features.h" 1 3 4 # 374 "/usr/include/features.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
Note that a simple program such as this:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
Compiled with this:
gcc -Wall -std=c99 -O0 -save-temps=obj main.c -o ./bin/main
Will produce a main.i
file that is about 682 lines long, with the main()
function shown above being right at the very end.
.i
files:My preference is to generate all intermediate files (.i
, .o
, .s
, rather than just the .i
file using -E
) all at once in a local bin
folder in the project like this:
mkdir bin
gcc -save-temps=obj foo.c -o ./bin/foo
Now you have the following in the "foo/bin" directory:
foo # compiled binary program (AKA: combined "object file", # "executable", "binary", "program", or "machine code") foo.i # intermediate, preprocessed C file foo.o # individual object file foo.s # assembly file
Run the program of course with:
./bin/foo
Note that the final output, the foo
executable file, is called the "compiled binary program", "program", (combined) "object file", "executable", "binary", or just "machine code", or "ones and zeros" (10101010). It is an object file in object file format, as are the individual "*.o" object files which are combined into one by the linker to create it. The linker combines all "*.o" object files into one in order to make the final foo
executable, or combined object file.
The GNU linker (ld
) manual states it as follows. See section "3.1 Basic Linker Script Concepts": https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts (emphasis added, as well as content in square brackets []
):
3.1 Basic Linker Script Concepts
We need to define some basic concepts and vocabulary in order to describe the linker script language.
The linker combines input files [individual *.o object files] into a single output file. The output file and each input file are in a special data format known as an object file format. Each file is called an object file. The output file is often called an executable, but for our purposes we will also call it an object file. Each object file has, among other things, a list of sections. We sometimes refer to a section in an input file as an input section; similarly, a section in the output file is an output section.
For more info. on object files, you can also see two of my other answers here:
The .i
files are also called as "Pure C files". In preprocessing stage
Header files will be included.
Macros will be replaced.
Comments are removed.
Used for conditional compilation.
If you look at the .i
file you can see these things.
Command to generate .i
file is-
gcc -E foo.c -o foo.i