2017-01-25 3 views
0

Я знаю, что включенные и заголовки будут скопированы в исходный файл во время процесса препроцессора.где включены и заголовки во время компиляции?

Я использую gcc для компиляции файла.

исходный файл (.c файл):

#include <stdio.h> 

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

Я могу увидеть их в файле ".И"

# 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. В файле сборки, где это включает stdio.h я добавил в исходном коде?

  2. Какова роль включений и заголовков во время компиляции? Как они влияют на процесс компиляции?

Заранее благодарен!

ответ

0

заголовки файлы в C и C++ обеспечивают компилятор с информацией , что он требует, чтобы проанализировать исходные файлы, в которых вы #include им. Вы можете указать #include в исходном файле , чтобы включить компилятор. После анализа файла источника и всех файлов заголовков #include компилятор может генерировать файл объектного кода, который может быть связан с другими в исполняемом файле. . Это соединение сделано вашим linker

Это совершенно не обязательно для всех информации, что позволяет компилятор разобрать исходный файл быть скопирован в любой форме, в объектный файл. После того, как послужил целью синтаксического анализа, подавляющее большинство обычно не используется. Рецепт позволяет приготовить блюдо. Когда вы приготовили блюдо, вы не ожидаете найти рецепт в нем.

Если вы генерировать и исследовать код сборки, который компилятор производит из некоторых исходных входного файла, что вы смотрите на это языке ассемблера перевод файла объекта что компилятор будет производить из того же входа , Любая информация, которая не нужна и отсутствует в объектном коде, также не нужна и отсутствует в коде сборки.

Большая часть информации в обычном файле заголовка определяет, в коде, интерфейсы программирования программных средств, что ваш собственный код будет использовать, но которые уже собраны в некоторой внешней библиотеке, что ваш собственный объект кода нужно будет связать.Эта информация позволяет компилятору генерировать объектный код, который может быть связан с внешней библиотекой по назначению и правильному пути.

В вашей сборке список, например, вы можете увидеть программу инициализации регистры , чтобы сделать вызов printf Как вы знаете, что это функция Standard C, реализованный в библиотеке времени выполнения C, что ваша программа будет связана с, , интерфейс которого указан в объявлении функции в <stdio.h>, который вы #included. Компилятор должен был <stdio.h> только для проверки того, что настройка printf вызов таким образом соответствует процедуре вызова, которую printf ожидает в библиотеке времени выполнения C. Ну, в вашем объектном коде, который printf звоните , настроен точно так, как вы видите в сборке, и <stdio.h> был расточительство как только это было сделано.

Дополнительная информация может быть просвещена this answer