C标准库中的函数定义在哪里?

我对源代码不感兴趣,我想知道C编译器(GCC)实际上是如何找到这些函数的。 就像在预处理器看到我已经包含stdio.h ,它在哪里找到定义函数体的文件?

编辑

我可能也应该说我正在使用Ubuntu 12.04,但是如果有一般答案,那也会有用。

gcc附带(二进制)目标文件( 不是 C源文件),它包含所有标准C函数的实现。 使用gcc将目标文件链接到可执行文件时,链接器会自动包含实现标准库函数的目标文件。 根据这个线程 ,该标准目标文件可能被称为libc.alibc.so

假设您在程序中包含对printf的调用。 当链接器尝试解析该调用的位置时,它将在libc.a找到printf的定义,并在libc.a创建函数调用点。

查看http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html并注意-nostdlib-nodefaultlibs选项。 您可以使用这些选项告诉gcc的链接器默认情况下包含标准库对象文件。

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  int main() { printf("Hello World!\n"); return 0; } 

让我们称之为ic

 $ gcc ic # 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),您可以指定许多不同的包含function。 基本上,-I指定的目录将在-isystem指定的目录之前进行搜索,然后在“标准系统包含目录”之前搜索这些目录(至少根据我的测试)。 区别在于-I可以用于任何#include指令,但是–isystem只能用于#include <...>但是,建议只使用-I作为#include“…… “由于搜索顺序的指令。 使用-I-确实给你很多控制权,因为任何-I之前使用的-I-将只搜索#include“…”而任何-I-之后使用的-I-将被搜索任何#include指令。 此外,使用-I-表示不会搜索当前目录中包含的文件,除非您还指定了-I。 (搜索当前目录)。

如果要获取默认支持的搜索目录列表,请尝试运行此命令: cpp -v < /dev/null这将运行没有输入的GNU C预处理器; 在此过程中,它将打印(给定-v标志)包含目录搜索路径。 你应该看到像“#include <...>搜索从这里开始:”这样的短语,然后是目录列表。 这些是您的标准包含搜索路径,按搜索顺序排列。

您的libc (或libstdc++ for C ++)可能位于Linux上的/usr/lib/usr/lib64中。 这些是共享库 ,你可以修改LD_LIBRARY_PATH变量来指定它们被搜索到的目录。一个实际的例子是你安装gcc的本地副本,很可能它会有一个标准库的更新版本而不是你的系统,所以你希望你的本地gcc启动它,即export LD_LIBRARY_PATH=/home/user/local-install/gcc/lib64

它查看环境变量设置的库路径。

阅读更多: http : //gcc.gnu.org/onlinedocs/cpp/Search-Path.html