Где определены функции в стандартной библиотеке C?

меня не интересует исходный код, я хочу знать, как компилятор C (GCC) фактически находит функции. Например, когда препроцессор видит, что я включил stdio.h, где искать файлы, определяющие тела функций?

редактировать

Я, вероятно, также должен сказать, что я использую Ubuntu 12.04, но если есть общий ответ, это тоже сработает.

5 ответов


gcc поставляется с (двоичными) объектными файлами (не исходные файлы C), которые содержат реализации всех стандартных функций C. Когда вы используете gcc связать объектные файлы в исполняемый файл, линкер автоматически включает объектные файлы, реализующие стандартные библиотечные функции. Согласно этой теме, что стандартный объектный файл, вероятно, будет называться libc.a или libc.so.

скажем, вы включаете вызов к printf в вашей программе. Когда компоновщик пытается решить, куда должен идти этот вызов, он найдет определение printf на libc.a, и сделайте вашу точку вызова функции там.

посмотреть http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html и примечание -nostdlib и -nodefaultlibs параметры. Вы можете использовать эти параметры, чтобы сказать gcc'линкер с не включить стандартные объектные файлы библиотеки по умолчанию.


gcc получает определения функции из библиотеки Си. Вы можете определить путь, который 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 и что вы найдете определения функций, используемых в коде в нем.


ваш вопрос связан с тем, где GCC ищет файлы заголовков. Он ищет в стандартных каталогах. Вы можете найти этой теме будет полезно:

с различными параметрами (такими как-I и-I - и-isystem) вы можете указать множество различных функций включения. В основном, каталоги, указанные by-I будет искать перед указанными-isystem, которые будут в свою очередь, искать до тех, в " стандартной системе включают каталоги " (по крайней мере, согласно моим тестам). Разница в том, что - Я могу использоваться для любой директивы #include, но-isystem будет использоваться только для #include <...> Тем не менее, рекомендуется только используйте -I для #include "...- директивы из-за порядка поиска. Использование-Я-действительно дает вам много контроля, потому что любой-я использовал раньше - Я-будет искать только для #include"..."в то время как любой-я использовал после-я - будет искать любую директиву #include. Кроме того, с помощью - I-означает, что текущий каталог не будет искать включенные файлы, если вы также не укажете-I. (поиск текущего справочник.)

Если вы хотите получить список поддерживаемых каталогов поиска по умолчанию попробуйте выполнить следующую команду:cpp -v < /dev/null Это работает препроцессор GNU C без ввода; в процессе он будет печатать (учитывая флаг-v) пути поиска каталога включения. Вы должны см. такие фразы, как " #include <...> поиск начинается здесь: "далее ля список директорий. Это ваши стандартные пути поиска включения, в того, что они искали.


код libc (или libstdc++ для C++) может быть расположен в любом /usr/lib или /usr/lib64 на Linux. Это общие библиотеки и вы можете изменить LD_LIBRARY_PATH переменная, чтобы указать, в каких каталогах они ищут. Практическим примером может быть установка локальной копии gcc, и, скорее всего, она будет иметь обновленную версию стандартной библиотеки в отличие от вашей системы, поэтому вы хотели бы, чтобы ваш локальный gcc запустился с этим вместо i.e export LD_LIBRARY_PATH=/home/user/local-install/gcc/lib64


он просматривает пути библиотеки, заданные переменной среды.

Подробнее:http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html