gpt4 book ai didi

c - (C) 如果不必直接提供源代码,stdlib 函数的实现如何在头文件中存储和链接?

转载 作者:太空宇宙 更新时间:2023-11-04 00:21:00 25 4
gpt4 key购买 nike

刚开始使用 C

像 stdlib 这样的库的头文件不包含它们提供的函数的实际实现代码。我知道像这样的库的实际源文本不需要编译,但是它具体是如何工作的? 这些库的实现细节是否包含在编译器中?

当您使用像 printf() 这样的函数时,包括头文件本质上是粘贴函数声明的代码,但通常也需要提供实现代码。它以什么形式存储?(以及存储在何处?)此编译器是否特定是否可以在不修改编译器行为的情况下编写自定义代码并以这种方式引用它?

我四处搜索,发现了一些相关但不具体的信息。这可能与没有很好地提出问题有关。谢谢。

最佳答案

当你链接一个程序时,编译器会隐式地为你的程序添加一些额外的库:

$ ls
main.c
$ cc -c main.c
$ cc main.o
$ ls
main.c main.o a.out

您可以通过 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...)

那么,如果我们在没有这些库的情况下进行链接会怎样?这很简单,只需直接使用链接器 (ld),而不是通过 cc 调用它。当你使用 ld 时,它不会给你这些额外的库,所以你会得到一个错误:

$ ld main.o
Undefined symbols:
"_printf", referenced from:
_main in main.o

printf() 的实现存储在标准 C 库中,它通常只是您系统上的另一个库...唯一的区别是当您编译C。

您可以使用 nm 找出库中的符号,因此我可以使用它在 libc 中找到 printf() :

$ nm -D /lib/x86_64-linux-gnu/libc-2.13.so | grep printf
...
000000000004e4b0 T printf
...

所以,现在我们知道 libcprintf(),我们可以使用 -lc 告诉链接器包含 >libc,这将消除有关 printf() 丢失的错误:

$ ld main.o -lc

可能还缺少其他一些位,这就是为什么我们使用 cc 而不是 ld 来链接我们的程序:cc 给了我们所有默认库。

关于c - (C) 如果不必直接提供源代码,stdlib 函数的实现如何在头文件中存储和链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24920313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com