C标准库中定义的功能在哪里



我对源代码不感兴趣,我想知道C编译器(GCC)实际上如何找到功能。就像在预处理器看到我包括stdio.h时,它在哪里可以找到定义功能主体的文件?

编辑

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

gcc带有(二进制)对象文件(不是 c源文件),其中包含所有标准C函数的实现。当您使用gcc将对象文件链接到可执行文件时,链接器自动包括实现标准库函数的对象文件。根据该线程,该标准对象文件可能称为libc.alibc.so

说您在程序中包括对printf的呼叫。当链接器试图解决该调用的位置时,它将在libc.a中找到printf的定义,并在此处使您的函数呼叫点。

查看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 <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 -is -isystem),您可以指定 许多不同的包含功能。基本上,目录指定 由-i将在-ISYSTEM指定的内容之前进行搜索,将 依次搜索"标准系统包括 目录"(至少根据我的测试)。区别在于 - 我可以用于任何#include指令,但是-isystem只能用于#include&lt; ...>,但建议仅使用它 由于搜索顺序,请使用-i用于#include" ..."指令。 使用-i确实可以给您带来很多控制,因为任何以前使用的 - -i-将仅搜索#include" ...",而在-i-我使用的任何#Include指令之后使用。此外, 使用-i-表示不会搜索当前目录 包括文件,除非您还指定-i。(搜索当前 目录)。

如果您想获取支持哪些搜索目录的列表 默认情况下,尝试运行此命令:cpp -v < /dev/null这是运行的 没有输入的GNU C预处理器;在此过程中,它将打印 (给定-v标志)包含目录搜索路径。你应该 请参阅" #include&lt; ...>搜索开始:"之类的短语 目录列表。这些是您的标准包含搜索路径, 按照他们搜索的顺序。

您的libc(或C 的libstdc++)可能位于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