0

I know the includes and headers will be copied into source file during preprocessor process.

I use gcc to compile the file.

source file(.c file):

#include <stdio.h>

int main(){
    printf("Hello World!!!");
    return 0;
}

I can see them in ".i" file

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 367 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 410 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 411 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 368 "/usr/include/features.h" 2 3 4
# 391 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 392 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4
.......

However, after generating the assembly file (.s), it seems all of them are gone.

    .file   "test.c"
    .section    .rodata
.LC0:
    .string "Hello World!!!"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"
    .section    .note.GNU-stack,"",@progbits 

My questions are:

  1. In the assembly file, where is the include stdio.h I added in the source code?

  2. What is the role of the includes and headers during compilation? How do they effect the compile process?

Thanks in advance!

tiger
  • 69
  • 9

1 Answers1

0

Header files in C and C++ provide the compiler with information that it requires in order to parse the source files in which you #include them. You #include them in a source file to enable the compiler to do that. Having parsed a source file, and all the #include-ed header files, the compiler is able to generate an object code file that is capable of being linked together with others in an executable. That linking is done by your linker

It is quite unnecessary for all of the information that enables the compiler to parse the source file to be copied in any form into the object file. Once it has served the purpose of parsing, the great majority of it is typically of no further use. A recipe enables you to cook a dish. When you have cooked the dish, you don't expect to find the recipe in it.

If you generate and examine the assembly code that the compiler produces from some input source file, what you are looking at is an assembly language translation of the object file that the compiler will produce from the same input. Any information that is unnecessary and absent in the object code is likewise unnecessary and absent in the assembly code.

Much of the information in a typical header file defines, in code, the programming interfaces of software facilities that your own code will make use of, but which are already compiled in some external library that your own object code will need to be linked with. This information enables the compiler to generate object code the can be linked with that external library in the intended and correct way.

In your assembly listing, for instance, you can see the program initializing registers to make a call to printf As you know, that is a Standard C function, implemented in the C runtime library that your program will be linked with, whose interface is specified by a function declaration in <stdio.h>, which you #included. The compiler needed <stdio.h> only to verify that setting up the printf call in this way conforms with the calling procedure that printf expects in the C runtime library. Well, in your object code that printf call is set up exactly as you see in the assembly, and <stdio.h> was waste material once that was done.

You may be further enlightened by this answer

Community
  • 1
  • 1
Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182