質問

ときに私のプログラムは、2つのファイルで構成されます:

main.cの

#include <stdio.h>

int main(void) { 
     printf("%lf\n",f());   
     return 0;
 }

func.c

double f(int a) {
 return 1;
}

コンパイラがすべてのエラーを表示しません。

私のプログラムは、一つだけのファイルで構成されている場合:

main.cの

#include <stdio.h>

int main(void) { 
     printf("%lf\n",f());   
     return 0;
 }

double f(int a) {
 return 1;
}

のVisual C ++ 2008コンパイラは次のエラーが表示されます:

Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1

缶誰でもこの奇妙な動作を説明する?

役に立ちましたか?

解決

両方のプログラムが間違っています。

範囲でプロトタイプがなければ、コンパイラは関数が返す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を出力しなかったが、コンパイラはそのf()intを戻し、割り当てd = f();intにその「double」に変換仮定ので0印刷です。それは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のプログラムを拒否します。

他のヒント

C)は関数(プロトタイプint funcを有していると仮定します。あなたはそれ以外の場合に語っていない限り。(Cのint型のFUNC()に注意することを;とint型のFUNC(無効);異なるものです)

は2番目のケースでは、あなたはそれがf()であると仮定して、コンパイラは、任意のプロトタイプを見ていないいるint f();への呼び出しを行います。その後、その上には別のプロトタイプを持っているf()ためのあなたの定義を見て - 。そして問題のエラー

彼らは別のコンパイル単位にしているように、

これは、1の場合には発生しません。

あなたの最初の例は、func.cを使用したことがない私はそれが何の定義がないため、コンパイラはf()についてやっている正確に何かわからないようにします。

あなたは異なるシグネチャを持つ2つの機能を持つことができない理由は2番目の例では、

は、私は知りませんが、あなたは、あなたが定義した関数を呼び出すされていません。あなたは、引数なしでf()を呼び出していますが、定義fは異なる機能になりint型をとります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top