関数プロトタイプ宣言がない場合のコンパイラーの処理

プログラムを分割する際に注意するべき第1の点は,関数プロトタイプによる関数の宣言です.あるコンパイル単位の中に関数の引用があった場合,もし関数プロトタイプがなければ,コンパイラの処理は次のようになります.

  1. その関数自体が同じコンパイル単位の引用箇所より前に存在する場合:コンパイラは関数と引数の型を正しく認識して処理します.この場合は関数プロトタイプがなくても問題ありません.
  2. その関数自体が同じコンパイル単位の引用箇所より後に存在する場合:コンパイラは,コンパイル単位の中ではじめて関数が引用された時点で,その関数が int型であると仮定して処理をすすめます(つまり,コンパイラは未定義の関数はすべて int型とみなすわけです).したがって,その後で関数自体の定義が現われたとき,その型が int型でなければ「関数の型が一致しない」というエラーメッセージを出力します.この場合はコンパイルは異常終了となります.
  3. その関数自体が同じコンパイル単位に存在しない場合:コンパイラは先の場合と同様に,はじめて関数が引用された時点で,その関数が int型であると仮定して処理をすすめます.コンパイルの終了までに関数の定義が現われなくても,他のコンパイル単位に存在するものと仮定するので,コンパイルエラーにはなりません.もし引用された関数の型が本来は int型でない場合,最終的に生成された実行ファイルの動作がおかしくなります.しかし,コンパイルとリンク自体は正常に終了します.

すなわち,関数プロトタイプがなくてもコンパイルに問題が生じない場合もありますが,多くの場合は関数プロトタイプによってあらかじめ関数の型を宣言しておく必要があります.特に分割コンパイルを行なう場合は,上記項目3に示すように,コンパイル単位どうしで関数の型に不一致があってもコンパイルエラーが生じません.したがって,このことによってプログラムの動作がおかしくなっても気付かない場合があります.