问题界面正在标记许多"Questions that may already have your answer",但我试图尽职尽责地检查是否有人问我到底在哪里 . 如果这是重复,我道歉 .
假设我有以下不正确的程序:
extern void undefined_function(void);
int main(int argc, char **argv)
{
undefined_function();
undeclared_function();
exit(0);
}
用gcc编译给出:
$ gcc warnings.c
warnings.c: In function ‘main’:
warnings.c:6:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
/tmp/ccVzjkvX.o: In function `main':
warnings.c:(.text+0x15): undefined reference to `undefined_function'
warnings.c:(.text+0x1f): undefined reference to `undeclared_function'
collect2: ld returned 1 exit status
$
I know why these warnings are emitted, and how to correct them - that is not my question.
从输出中可以清楚地看出,gcc正在以不同的方式处理 exit()
与其他未定义/未声明的函数,因为它认为它是"built-in function"
对于给定的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: no symbols
$
3 回答
该列表很长,而且非常特定于平台 . C标准库中的许多(但并非全部)函数(有时)被视为内置函数 . 但是,还有一大堆与特定处理器指令和其他硬件功能相关的内置函数 . 它们记录在从here;特别链接的各个页面中,请参阅here, here, here, here和here.
在仔细研究了gcc文档之后,我想我找到了一个合理的部分答案(though this answer is more complete in its references):
http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Other-Builtins.html#Other-Builtins
“GCC在标准C库中包含 many of the functions 的内置版本”(强调我的) . 我认为这意味着 most but not all 标准库函数是内置的 .
文档继续介绍适用于c标准各个级别的几个列表:
“ISO C90函数
abort
,abs
,acos
,asin
,atan2
,atan
,calloc
,ceil
,cosh
,cos
,exit
,...”不是gcc内置的标准库函数的示例是bsearch() . 如果我在程序中添加对此的调用,没有
#include <stdlib.h>
并使用-Wimplicit-function-declaration
进行编译,我得到:鉴于
exit()
,我得到:您正在编译C,它允许隐式声明,因此您的“exit”是隐式声明的 . 并且编译器信任您以后定义它 .
隐含的声明很好,如果你隐含退出通常的行为(隐含的原型与实际的原型相同)它会没事的 .
GCC只能告诉你内置的内容,因为你知道对于C编译器,stdlib会在那里 . 这是它知道存在的唯一功能(内置),告诉你你错误地暗示
否则我可以在我的桌面上定义一个原型的头文件,当在其他地方编译某些东西时会收到关于它的警告 . GCC必须扫描到处并且这是不可取的......所以,如果您隐式定义某些内容,稍后在翻译单元或实际版本(或其他隐含的)不同意中,您将只会收到类似这些的隐式警告 .
GCC知道stdlib =内置的 .
Addendum
GCC接受你的说法,即未定义的函数将存在,使用implict声明的东西,并没有任何矛盾,所以它很好 . 它不知道
undeclared_function
应该是什么样子,但它知道exit
应该是什么样的 .然后如你所知,链接器抛出一个拟合(当然是正确的),因为它无法找到它们 .