C (C99 より前) では、関数を使用するために関数を宣言する必要はありません。コンパイラは、関数が渡された昇格されたパラメーターの型を受け取ると想定し、関数が を返すと想定しますint
。ただし、これは非常に問題になる可能性があり、関数が定義されていない場合の動作は未定義です。これを見てみましょう:
/* file1.c */
void foo(char a, char b) {
/* doing something ... */
}
/* main.c */
int main(void) {
char a = 'a', b = 'b';
/* char variables are promoted to int
before being passed */
foo(b, a);
}
呼び出し時に関数の宣言がない場合、型がプロモート ( char -> int, float -> double
) されるため、メモリ内の適切な場所で引数を渡すことができなくなります。b にアクセスすると、パラメーターの興味深い値が得られる可能性があります。vararg functions
サイド ノードとして、 like prinft
、またはプロトタイプを持たない関数 (void f()
パラメーターの型とカウントに関する情報がないなど) に引数を渡すと、同じ問題が発生します。va_arg
これが、昇格された型を使用して常に可変引数にアクセスする必要がある理由です。そうしないと、GCC から警告が表示されます。
この問題に遭遇しないように、常に適切なヘッダー ファイルを含めてください。
編集:char literals
(like 'a'
) は常にint
C の型であることを指摘してくれた Chris に感謝します