除了stdlib.h之外,exit()函数还在哪里声明过?

3

尝试编译下面的示例时,我收到了一个警告:

>gcc -o file file.c
file.c: In function ‘main’:
file.c:12: warning: incompatible implicit declaration of built-in function ‘exit’

经过一番搜索,我发现示例缺少语句#include <stdlib.h>

那么exit()函数是在哪里声明的呢?库stdio.h没有声明它。我的代码也没有。如果编译器支持它,为什么会出现警告?另外,为什么在stdlib.h中重新定义它?

示例:

#include <stdio.h>

int main()
{
    char *fn = "./test.txt";
    FILE *fp;

    if((fp = fopen(fn, "w"))==NULL)
    {
        printf("Cannot open file '%s' for writing.\n", fn);
        exit(1);
    }

    fprintf(fp, "Hello, world!\n");

    if(fclose(fp)==0)
        printf("File '%s' closed successfully.\n", fn);
    else
        printf("Error closing file '%s'.\n", fn);

    return 0;    
}

我认为当您引用一个不存在的函数时,其行为是未定义的。 - Rafe Kettler
1个回答

13

即使你没有包含标准头文件,GCC也知道它们的内容,并在隐式(或推断)声明的函数与包含头文件后的声明不够相同时发出警告。

由此推断,exit()的类型为:

extern int exit();  // Indeterminate argument list

这与官方声明不同:

extern void exit(int);
因此就有了这个警告。习惯它,修复代码。
“充分”这个词是用来描述当没有注释掉exit()的声明时,这段代码可以编译通过而不会有警告,但是当它缺少时会产生警告。
extern void exit();
int main(int argc, char **argv)
{
    if (argc > 1 && argv[0] != 0)
        exit(1);
    return(0);
}

结束了“鼬词”(weasel words)。


注意:早期的C语言大量使用隐式函数声明。C89开始鼓励使用正确的函数定义,部分原因是确保每个标准函数都有一个声明它的头文件。(POSIX也通过确保其定义的所有函数都在头文件中声明来提供帮助。) C99更进一步,它表示预先定义的和C89中的“implicit int”函数解释不再有效。现在,GCC通过识别函数来帮助您修复代码。您可以使用以下选项:

-Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition

如果(像我一样)你在古老的代码库上工作,且这些代码库没有进行现代 C 编码标准的全面更新,那么这将帮助你捕捉问题。


非常感谢您如此详尽的回复。 - artdanil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接