1

提问界面标记了许多“可能已经有你答案的问题”,但我已尝试尽职调查以检查是否有任何人在问我在这里的确切内容。如果这是重复的,我很抱歉。

假设我有以下不正确的程序:

外部无效未定义函数(无效);
int main(int argc, char **argv)
{
    未定义函数();
    undeclared_function();
    退出(0);
}

用 gcc 编译给出:

$ gcc 警告.c
警告.c:在函数'main'中:
warnings.c:6:2:警告:内置函数“退出”的隐式声明不兼容 [默认启用]
/tmp/ccVzjkvX.o:在函数“主”中:
warnings.c:(.text+0x15): undefined reference to `undefined_function'
warnings.c:(.text+0x1f): undefined reference to `undeclared_function'
collect2: ld 返回 1 个退出状态
$

我知道为什么会发出这些警告,以及如何纠正它们——这不是我的问题。

从输出中可以清楚地看出,gccexit()与其他未定义/未声明的函数的处理方式不同,因为它认为它是“内置函数”

对于给定的 gcc,我如何判断 gcc 认为是“内置函数”的函数列表是什么?它究竟是c标准库函数列表还是其他东西?

我考虑过这样做nm libc.so,但在我的 Ubuntu VM 上,这个 glibc 似乎已被剥离,因此在这方面没有有用的信息:

$ nm /lib/x86_64-linux-gnu/libc.so.6
nm:/lib/x86_64-linux-gnu/libc.so.6:无符号
$
4

3 回答 3

1

该列表很长,并且非常特定于平台。C 标准库中的许多(但绝不是全部)函数(有时)被视为内置函数。但也有大量与特定处理器指令和其他硬件特性相关的内置函数。它们记录在从此处链接的各个页面中;特别是,请参见此处、 此处、 此处、 此处此处。

于 2013-11-14T19:37:51.330 回答
0

在深入研究 gcc 文档之后,我想我找到了一个合理的部分答案(尽管这个答案在其参考文献中更完整):

http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Other-Builtins.html#Other-Builtins

“GCC 包括标准 C 库中许多函数的内置版本” (强调我的)。我认为这意味着大多数但不是所有标准库函数都是内置的。

该文档继续列出了适用于各个级别的 c 标准的几个列表:

“ISO C90 功能abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, ...”


不是 gcc 内置的标准库函数的示例是bsearch(). 如果我在程序中添加对此的调用,没有#include <stdlib.h>和编译-Wimplicit-function-declaration我得到:

warnings.c:5:2: warning: implicit declaration of function ‘bsearch’ [-Wimplicit-function-declaration]

而对于exit(),我得到:

warnings.c:8:2: warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]
warnings.c:8:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
于 2013-11-14T19:34:38.580 回答
-1

您正在编译允许隐式声明的 C,因此您的“退出”是隐式声明的。并且编译器信任您稍后定义它。

隐式声明很好,如果您以通常的行为暗示退出(隐含的原型与实际原型相同),那很好。

GCC 只能告诉您有关内置的​​信息,因为您知道对于 C 编译器,stdlib 将在那里。这些是它知道存在(内置)的唯一功能,可以告诉您您的暗示是错误的

否则我可以在我的桌面上有一个定义原型的头文件,并且当在其他地方编译某些东西时会得到一个关于它的警告。GCC 将不得不到处扫描,这是不可取的......等等,如果您隐式定义某些内容并且稍后在翻译单元或实际版本(或另一个隐式)不同意,您只会收到这样的隐式警告。

GCC 知道 stdlib = 内置。

附录

GCC 相信你的话,未定义的函数将存在,使用隐含声明的东西,没有什么矛盾的,所以没关系。它不知道实际undeclared_function应该是什么样子,但它知道exit应该是什么样子。

然后如您所知,链接器会抛出一个合适的(当然是正确的),因为它找不到它们。

于 2013-11-14T19:17:00.330 回答