Where do we use .i files and how do we generate them?

后端 未结 2 1323
挽巷
挽巷 2021-02-04 13:23

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

相关标签:
2条回答
  • 2021-02-04 13:34

    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:

    1. all header files included
    2. macros replaced
    3. and comments removed

    ...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.

    How to generate all intermediate files, including the .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
    

    Notes about "object files" and "executables"

    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:

    1. How do I find out at compile time how much of an STM32's Flash memory and dynamic memory (SRAM) is used up?
    2. Convert binutils `size` output from "sysv" format (`size --format=sysv my_executable`) to "berkeley" format (`size --format=berkeley my_executable`)
    0 讨论(0)
  • 2021-02-04 13:58

    The .i files are also called as "Pure C files". In preprocessing stage

    1. Header files will be included.

    2. Macros will be replaced.

    3. Comments are removed.

    4. 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
    
    0 讨论(0)
提交回复
热议问题