编译期间包含和标题在哪里?

时间:2017-01-25 16:14:44

标签: gcc compilation

我知道在预处理程序进程中,包含和标题将被复制到源文件中。

我使用gcc编译文件。

源文件(.c文件):

#include <stdio.h>

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

我可以在&#34; .i&#34;档案

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

但是,在生成程序集文件(.s)后,似乎所有这些文件都已消失。

    .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 

我的问题是:

  1. 在汇编文件中,我在源代码中添加的include stdio.h在哪里?

  2. 编译期间包含和标题的作用是什么?它们如何影响编译过程?

  3. 提前致谢!

1 个答案:

答案 0 :(得分:0)

C和C ++中的头文件为编译器提供信息 它需要解析您所在的源文件 #include他们。你在源文件中#include 使编译器能够做到这一点。解析了一个来源 文件和所有#include - ed头文件,编译器 能够生成能够的目标代码文件 在可执行文件中与其他人链接在一起。那个联系 由您的linker

完成

所有人都没有必要 启用编译器解析源的信息 要以任何形式复制到目标文件中的文件。一旦它 已经服务于解析的目的,绝大多数 它通常没有进一步的用途。食谱使您可以烹饪菜肴。什么时候 你做了这道菜,你不希望在里面找到食谱

如果生成并检查编译器的汇编代码 从一些输入源文件生成,你正在看的是 目标文件的汇编语言翻译 编译器将从相同的输入产生。任何信息 是不必要的,并且在目标代码中不存在同样是不必要的 并且在汇编代码中没有。

典型头文件中的大部分信息都定义了, 在代码中,软件设施的编程接口是您自己的代码 将使用,但已经在一些外部库中编译自己的对象 代码需要与之链接。这个信息使 编译器生成的对象代码可以与之链接 外部图书馆以预期和正确的方式。

例如,在汇编列表中,您可以看到程序初始化寄存器 拨打printf如你所知,这是一个标准C功能,已实施 在您的程序将链接的C运行时库中, 其接口由<stdio.h>中的函数声明指定,您#included。 编译器仅需要<stdio.h>来验证设置printf 以这种方式调用符合printf期望的调用过程 在C运行时库中。好吧,在printf调用 的目标代码中 完全如您在装配中看到的那样设置,<stdio.h>一旦完成就是废料。

您可能会被this answer

进一步开悟