2011-01-10 2 views
1

タイトルが言うように、私はこのエラーの原因を知っていますが、コンパイラがこの状況でなぜそれを与えるのかを知りたいと思います。関数がCで定義される前に関数を使用しているときの暗黙の宣言は、なぜコンパイラーがこれを理解できないのですか?

例:

main.cの

void test(){ 
    test1(); 
} 

void test1(){ 
    ... 
} 

それはその宣言を読む前に、私は明白な問題を見ることができますTEST1()への呼び出しに到達するコンパイラなどの暗黙的な宣言の警告を与えるだろうこれは(戻り値の型が分からない)ものですが、なぜコンパイラーがすべての関数宣言を取得するための単純なパスを実行できないのでしょうか?それはやるのがとても簡単なようで、他の言語でも同様の警告が表示されたとは思いません。

私が見落としているこの状況で、この警告の特定の目的があるかどうか誰にも分かりますか?

答えて

0

短い答え:Cはうまくありません。 :-)

長い答え:Cコンパイラとリンカはまったく別物です。異なるソースファイル間で異なる機能を定義し、それらをリンクすることができます。この場合、別のライブラリソースファイルにtest1を定義していたとします。コンパイラは、test1については、他のファイルをコンパイルするまで知らないでしょうし、別のファイルを別々にコンパイルするので、コンパイル時にそれを知ることができません。test。したがって、他の場所ではtest1が実際に定義されており、その署名はここにあります。そのため、通常、ヘッダファイル(.h)を使用する必要があります。このファイルでは、関数を使用する必要がある他のソースファイルが含まれています。

+0

私は推測すると、それはずっと前に設計されたツールから二日酔いだと思います! – rolls

3

これは、Cの定義方法です。

使用前に宣言があります。シンボルを使用する前にシンボルを宣言するようにしてください。

ほとんどの場合、コンパイラの作業を簡単にするためです。

5

Cはかなり古い言語なので、1972年にさかのぼると思いますが、これはメモリーとスピードの制約のために意図的に行われたものです。

コンパイラは、ファイルを1回スキャンしてコンパイルに必要なものすべてを知っている必要があります。 2回のパスをしなければならないのはより高価なので、このルールは今日まで生き残っています。

また、このルールは、コンパイラライターの人生を楽にしています。 IDEのオートコンプリートのための人生は言うまでもありません。

したがって、プログラムライターのための小さな悩みは、コンパイラライターやIDEメーカーなどの人生を楽にすることを意味します。

ああ、あなたのプログラムはより速くコンパイルされます。あなたの手に数百万のコードベースを持っていれば悪くない。

0

このように見えるかもしれませんが、この方法でも時間を節約できます!あなたが何千ものファイルを持つコンパイルユニットをコンパイルしているとしましょう。シナリオでは、コンパイラはまず何千ものファイルを見分けて、 "ああ、この関数は存在しません。実装された方法は、未定義の関数が見つかると直ちにコンパイルを中断させます。これは時間を節約します。

+0

定義されているときを除いて、間違った順序でしかありません。それはあなたの時間を無駄にする! – rolls

関連する問題