2012-07-25 9 views
20

これはコンパイルしますなぜ私は思ったんだけど:Cでのプロトタイプと関数の定義が異なるのはなぜですか?

int test(); 

int main() { return test((void*)0x1234); } 
int test(void* data) { return 0; } 

コンパイラがそのことについて任意のエラー/警告を発しません。なぜ(私は、GCCを打ち鳴らすを試してみましたか)? 戻り値を変更すると、コンパイルされませんが、引数が異なる可能性があります。

+1

[C void arguments](http://stackoverflow.com/questions/693788/c-void-arguments)の可能な複製 –

答えて

28

int test(); 

へ:

int test(void); 

、あなたが取得します予想されるエラー:

foo.c:4: error: conflicting types for ‘test’ 
foo.c:1: error: previous declaration of ‘test’ was here 

int test();は単にint test(void);ないパラメータを取らない関数を宣言し、実際の関数プロトタイプであるのに対し、任意パラメータ(及びtestあなたのその後の定義と互換性を持つようになり)をとる関数を宣言(およびからですではなく、であり、以降の定義と互換性があります)。

+3

+1、C言語の用語で述べると、 'int test()'は単にプロトタイプではなく単に宣言です。 –

+0

しかし、そのような動作は間もなく廃止される予定です(少なくとも、これはISO C11が教えてくれるものです)。 – AnArrayOfFunctions

15
int test(); 

の関数宣言では、パラメータが指定されていないということは、関数が不特定多数の引数を取ることを意味します。

この関数は引数をとらないことを意味

int test(void); 

とは異なります。

パラメータのない関数宣言は、関数宣言の古いCスタイルです。 Cはこのスタイルを時代遅れのものとしてマークし、その使用を嫌う。要するに、それを使用しないでください。あなたのケースでは

、正しいパラメータ宣言と関数宣言を使用する必要があります:あなたが変更した場合

int test(void *data); 
+0

私はいつもCがそれを忘れる!たとえそれが「int test(void);」であっても、TUを超えていても、診断を発行する必要はありません。 – Flexo

関連する問題