2016-05-11 4 views
3

Я не касался C++ какое-то время, и этот вопрос может быть глупым, но это действительно беспокоит меня какое-то время.Где компилятор находит `` printf``?

Пусть у меня есть следующие программы: гр

#include <stdio.h> 

int main() 
{ 
    int i; 
    for(i=0; i<10; i++) 
    { 
    printf("Hello World!\n"); 
    } 
    return 0; 
} 

Я знаю причину, я включаю stdio.h это потому, что я называю printf в main, но мне интересно, как компилятор будет знать, где найти реализацию printf() во время компиляция? stdio.h предоставляет только прототип функции, но что именно происходит во время компиляции?

Будет ли определенный префиксный путь, который компилятор знает для поиска реализации printf? Если да, то как их найти?

Спасибо большое!

+9

Это линкер, который на самом деле находит его. И да, путь для поиска стандартных библиотек предопределен. –

+0

@ πάνταῥεῖ Не могли бы вы объяснить немного больше? Благодаря! – zack

+0

[Дополнительная информация] (http://stackoverflow.com/questions/23181905/standard-c-library-linking) –

ответ

7

Скорее всего, если вы используете систему linux, используемая библиотека C - это glibc. GCC фактически не обеспечивает реализацию библиотеки C, а только файлы заголовков. Это задача библиотеки C на самом деле реализовать определение этих функций. В Linux есть что-то, что называется «разделяемые библиотеки», которые динамически загружаются программами, которые в ней нуждаются. Например:

ldd /usr/bin/gcc 
    linux-vdso.so.1 (0x00007ffd9e9f8000) 
    libm.so.6 => /lib64/libm.so.6 (0x00007ff9a35a6000) 
    libc.so.6 => /lib64/libc.so.6 (0x00007ff9a31de000) 
    /lib64/ld-linux-x86-64.so.2 (0x000055953c573000) 

Вы можете отключить увязывание libc пропускания -nostdlib и ссылки в вашей собственной библиотеке C. Существуют также другие способы замены определений, предоставляемых библиотекой C, например, ссылки на ваши собственные malloc и т. Д. Линкеру разрешено только найти одно определение для любого данного объявления, и поскольку в C нет имени, то это легко сделать.

Это упрощенное объяснение и не упоминает встроенные функции, математическую библиотеку и т.п.

1

printf является частью стандартной библиотеки, которая называется «стандартной», поскольку по умолчанию она связана с компилятором C. Стандартная библиотека обычно предоставляется операционной системой или компилятором. В большинстве Linux-систем он находится в libc.so, тогда как в MS Windows C Library предоставляется файл времени исполнения Visual C msvcrt.dll.

0

После некоторого копания, следующее объяснение имеет больше смысла для меня:

короткой версия

заголовочного файл содержит объявление, что потребности компилятора, но не реализации. Соответствующий файл библиотеки имеет такие. Компилятору нужны файлы заголовков, но не библиотеки; компоновщику нужны библиотеки, а не файлы заголовков.

длинная версия

файл Заголовок не содержит определение функции printf() (т.е. его реализации.), Который содержится в стандартной библиотеке ввода/вывода C (т.е. glibc).Компилятор не может создать машинные инструкции, которые будут вызывать функция printf() бежать, потому что он не знает, где printf() реализация; он не может создать вызов этой функции. Вместо этого компилятор помещает нотацию в исполняемый файл, который говорит, более или менее, вызов printf() должен быть разрешен компоновщиком.

Линкером является отдельная программа, которая запускается после компилятора. Он рассматривает все неразрешенные символы в программе , такие как printf() и пытается решить их, просмотрев их местоположения в библиотеках программного обеспечения , которые необходимы программе. В этом случае компоновщику необходимо найти в библиотеке стандартного ввода-вывода C значение функции printf() , чтобы он мог исправлять код для совершения вызова (ldd /usr/bin/gcc или gcc -v foo.c -Wl --verbose). Библиотека стандартного ввода-вывода C является специальной, поскольку она используется почти в каждой программе на C, и поэтому многие реализации C включают ее в библиотеке времени выполнения C. Это позволяет компоновщику легко найти его.

Смежные вопросы