Ste*_*ley 1 c compiler-construction precompiled-headers
新的使用C
像stdlib这样的库的头文件不包含它们提供访问的函数的实际实现代码.据我所知,编译这样的库的实际源文本不需要编译,但具体如何? 这些库的实现细节是否包含在编译器中?
当你使用像printf()这样的函数时,包括头文件基本上粘贴在函数声明的代码中,但通常也需要实现代码. 它存储的形式是什么?(以及在哪里?)这个编译器是否具体?是否可以编写自定义代码并以这种方式引用它而无需修改编译器的行为?
我一直在寻找并找到一些相关但没有具体的信息.这可能与没有很好地制定问题有关.谢谢.
链接程序时,编译器将隐式向程序中添加一些额外的库:
$ ls
main.c
$ cc -c main.c
$ cc main.o
$ ls
main.c main.o a.out
Run Code Online (Sandbox Code Playgroud)
您可以发现程序使用的额外库ldd.这里有三个链接到程序中的库,我没有要求它们中的任何一个:
$ ldd a.out
linux-vdso.so => (0x00...)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00...)
/lib64/ld-linux-x86-64.so.2 (0x00...)
Run Code Online (Sandbox Code Playgroud)
那么,如果我们没有这些库链接会发生什么?这很容易,只需ld直接使用linker(),而不是通过它cc.当您使用时ld,它不会为您提供这些额外的库,因此您会收到错误:
$ ld main.o
Undefined symbols:
"_printf", referenced from:
_main in main.o
Run Code Online (Sandbox Code Playgroud)
实现printf()存储在标准C库中,它通常只是系统中的另一个库...唯一的区别是它在编译时自动包含在程序中.
可以使用nm找出符号在图书馆,这样我就可以用它来寻找printf()在libc:
$ nm -D /lib/x86_64-linux-gnu/libc-2.13.so | grep printf
...
000000000004e4b0 T printf
...
Run Code Online (Sandbox Code Playgroud)
所以,现在我们知道libc了printf(),我们可以用-lc告诉链接,包括libc,这将摆脱对错误的printf()是丢失:
$ ld main.o -lc
Run Code Online (Sandbox Code Playgroud)
可能还有其他一些缺失,这就是为什么我们cc用来链接我们的程序而不是ld:cc给我们所有的默认库.