首页 文章

隐式声明警告:内置函数是什么?

提问于
浏览
1

问题界面正在标记许多"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 回答

  • 0

    该列表很长,而且非常特定于平台 . C标准库中的许多(但并非全部)函数(有时)被视为内置函数 . 但是,还有一大堆与特定处理器指令和其他硬件功能相关的内置函数 . 它们记录在从here;特别链接的各个页面中,请参阅here, here, here, herehere.

  • -1

    在仔细研究了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函数 abortabsacosasinatan2atancallocceilcoshcosexit ,...”


    不是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]
    
  • 1

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

    隐含的声明很好,如果你隐含退出通常的行为(隐含的原型与实际的原型相同)它会没事的 .

    GCC只能告诉你内置的内容,因为你知道对于C编译器,stdlib会在那里 . 这是它知道存在的唯一功能(内置),告诉你你错误地暗示

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

    GCC知道stdlib =内置的 .

    Addendum

    GCC接受你的说法,即未定义的函数将存在,使用implict声明的东西,并没有任何矛盾,所以它很好 . 它不知道 undeclared_function 应该是什么样子,但它知道 exit 应该是什么样的 .

    然后如你所知,链接器抛出一个拟合(当然是正确的),因为它无法找到它们 .

相关问题