Где определены функции в стандартной библиотеке C?
Мне не интересен исходный код, я хочу знать, как C-компилятор (GCC) действительно находит функции. Как и в случае, когда препроцессор видит, что я включил stdio.h
, где он ищет файлы, которые определяют тела функций?
Edit
Я должен, вероятно, также сказать, что я использую Ubuntu 12.04, но если есть общий ответ, это тоже сработает.
Ответы
Ответ 1
gcc
поставляется с (двоичными) объектными файлами (а не с исходными файлами C), которые содержат реализации всех стандартных функций C. Когда вы используете gcc
для связывания объектных файлов в исполняемый файл, компоновщик автоматически включает в себя объектные файлы, которые реализуют стандартные функции библиотеки. Согласно этой теме, этот стандартный объектный файл, вероятно, будет называться libc.a
или libc.so
.
Скажите, что вы включаете вызов printf
в свою программу. Когда компоновщик пытается решить, куда должен идти этот вызов, он найдет определение printf
в libc.a
и сделает там свою функцию.
Посмотрите http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html и обратите внимание на опции -nostdlib
и -nodefaultlibs
. Вы можете использовать эти параметры, чтобы сообщить не включать стандартные файлы объектов библиотеки по умолчанию.
Ответ 2
gcc
получает определения функций из библиотеки C. Вы можете определить путь, на который gcc
будет выглядеть, по умолчанию, для него, говоря:
ld --verbose | grep SEARCH_DIR
Это приводит к /usr/lib
в моей системе.
Попробуем найти, содержит ли библиотека символ для стандартной функции, например scanf
:
nm -A /usr/lib/libc.so | grep scanf
Результаты включают:
/lib/libc.so:0000000000042a90 T scanf
Рассмотрим небольшой пример:
#include <stdio.h>
int main() {
printf("Hello World!\n");
return 0;
}
Позволяет называть его i.c
:
$ gcc i.c # Compile
$ ldd ./a.out # Try to find dependencies
./a.out:
-lc.12 => /usr/lib/libc.so.12
Последняя команда по существу подразумевает, что двоичный файл зависит от /usr/lib/libc.so.12
и что вы найдете определения функций, используемых в этом коде.
Ответ 3
Ваш вопрос связан с тем, где GCC ищет файлы заголовков. Он ищет стандартные каталоги. Вы можете найти этот поток, который будет полезен:
С различными параметрами (например, -I и -I- и -системой) вы можете указать множество различных функций включения. В основном, указанные каталоги по -I будет выполняться поиск до тех, что указаны в -системе, которая будет в свою очередь, проводится поиск до тех, кто входит в стандартную систему (по крайней мере, согласно моим тестам). Разница в том, что -I можно использовать для любой директивы #include, но -система будет использоваться только для #include <... > Тем не менее, это рекомендуется только используйте -I для #include "..." директивы из-за порядка поиска. Использование -I- действительно дает вам большой контроль, потому что любой - я использовал раньше -I- будет искать только для #include "...", в то время как любой -I, используемый после -I-, будет искать любую директиву #include. К тому же, использование -I- означает, что текущий каталог не будет искать включены файлы, если вы также не указали -I. (поиск текущих каталог).
Если вы хотите получить список поддерживаемых каталогов поиска по умолчанию попробуйте запустить эту команду: cpp -v < /dev/null
Это выполняется препроцессор GNU C без ввода; в процессе он распечатает (учитывая флаг -v) пути поиска каталога включения. Вам следует см. фразы типа "#include <... > поиск начинается здесь:", за которым следует список каталогов. Это ваши стандартные пути поиска включения, в порядке их поиска.
Ответ 4
Ваш libc
(или libstdc++
для С++) может находиться в /usr/lib
или /usr/lib64
в Linux. Это разделяемые библиотеки, и вы можете изменить переменную LD_LIBRARY_PATH
, чтобы указать, какие каталоги они искали. Практическим примером будет установка локальной копии gcc и, скорее всего, она будет обновлена версии стандартной библиотеки, в отличие от вашей системы, поэтому вы хотели бы, чтобы ваш локальный gcc запускался с этим, т.е. export LD_LIBRARY_PATH=/home/user/local-install/gcc/lib64
Ответ 5
Он просматривает пути библиотек, заданные переменной окружения.
Подробнее: http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html