1

以下の例をコンパイルしようとすると、警告が表示されました。

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

いくつかの検索の後、 example に statement が欠落していることに気付きました#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;    
}
4

1 に答える 1

12

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);
}

イタチの言葉の終わり。 ]


注: 標準化前の C では、暗黙の関数宣言が頻繁に使用されていました。C89 では、すべての標準関数にそれを宣言するヘッダーがあることを保証することによって、適切な定義の使用を奨励し始めました。(POSIX は、それが定義するすべての関数がヘッダーで宣言されることを保証することによっても助けました。) C99 は、関数の先行標準および C89 の「暗黙的な int」解釈がもはや有効ではないと言って、さらに一歩前進しました。GCC は、関数を特定することにより、コードを修正するのに役立ちます。次のオプションを使用できます。

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

(私のように) 最新の C コーディング標準にオーバーホールされていない時代遅れのコード ベースで作業している場合に、問題を発見するのに役立ちます。

于 2011-03-11T19:47:24.643 に答える