質問: C言語入門 (ASCII SOFTWARE SCIENCE Language)に > > できるだけ ANSI 規格に準拠して関数はプロトタイプ宣言をするようにしましょう。プロトタイプ宣言がされている関数の引数については、それが正しい型であるか否かをコンパイラがチェックするので、引数の型の不整合をコンパイル時に検出できます。 > > > と書いてあったので ``` int factorial(int); int main(void) { char x=5; printf("%d!=%d",x,factorial(x)); return 0; } int factorial(int n) { if (n==1) return (1); else return (n*factorial(n-1)); } ``` と書いてgccでコンパイルしたんですが、コンパイル時にエラーが出ませんでした。 (factorialはintなのに、実引数のxはchar型) gccでは引数の型の不整合をチェックしないのでしょうか? (gccのバージョンは4.7.2です)
回答: `char`→`int`とサイズを大きくする方向へは暗黙の型変換が認められているため特に警告されることはありません。 > > 型が大きい方への変換であろうとも、暗黙の型変換ができるような場合は不整合と見なされず、エラーにならないという事ですか。型の不整合のチェックというのは結構アバウトなんですね。びっくりしました。 > > > 別質問でC言語にはバージョンがあることが紹介されていますが、この中で「最初のC」ではプロトタイプ宣言の中に引数情報が含まれておらず、「関数が存在する」ことしか宣言されていませんでした。 この場合、コンパイラーは引数をどのように扱うか分からないわけですが、そこで呼び出し規約に従って処理されます。具体的には呼び出しの際、整数は`int`に拡張され、実数は`double`に拡張されることが定められていました。もちろん呼び出された関数側としてもそのような引数しか受け取れないことになります。 > > > ``` > void tekitou(void); > void tekitou(); > > ``` > > と前者のようにプロトタイプ宣言の引数部に`void`を記述するのもこのためです。後者のように`void`を省略してしまうと、引数が存在しないのか、古いソースコードで引数が明示されていないのか判別できなくなります。 なお、引数情報のないプロトタイプ宣言は古い概念ですが、現在においても可変引数をとる関数(の可変引数部分)については依然として引数情報が含まれていないため今なお有効な概念です。 例えば`printf()`に`float`を渡しても呼び出し規約によって`double`に変換されているため`%lf`とフォーマット指定する必要があるのはこのためです。