両方のプログラムが間違っています。
スコープ内にプロトタイプがない場合、コンパイラーは、関数がint
不特定の数のパラメーターを返し、受け取ると想定します。
ファイルを少し変更してみましょう。
$ cat func.c
double f(int a) {
return 1.0;
}
$ cat main.c
#include <stdio.h>
int main(void) {
double d = f();
printf("%lf\n", d);
return 0;
}
コンパイルすると、gccが警告します(Visual C ++も準拠モードである必要があります)。しかし、警告は無視しましょう。
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test
func.c:1: warning: unused parameter 'a'
main.c: In function 'main':
main.c:4: warning: implicit declaration of function 'f'
$ ./test
0.000000
1は出力されませんでしたが、0が出力されました。これは、コンパイラががをf()
返すと想定しint
、割り当てがその「 」を。にd = f();
変換したためです。コンパイラーは、コードが(暗黙的に)宣言された方法で定義されていないことを認識できなかったため、コードをコンパイルしました。しかし、上記のプログラムをコンパイルすることは標準では必要とされていないので、コンパイラはそれを拒否した可能性があります(たとえば試してみてください!)int
double
f()
gcc -Werror
すべてが1つのファイルにある場合:
$ cat func.c >>main.c
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test
main.c:4: warning: implicit declaration of function 'f'
main.c: At top level:
main.c:9: error: conflicting types for 'f'
main.c:4: error: previous implicit declaration of 'f' was here
main.c:9: warning: unused parameter 'a'
これで、コンパイラは競合を認識し、エラーメッセージを表示します。ただし、コンパイラは上記のプログラムを拒否する必要はありません。拒否する場合としない場合があります。
f()
ほとんどのコンパイラは、別の変換ユニットに関数が正しく定義されているかどうかがわからないため、最初のプログラムを拒否しません。彼らはあなたがそうしないことを知っているので2番目のプログラムを拒否します。