私がこの機能を持っているとしましょう:
int func2() {
printf("func2\n");
return 0;
}
今、私はポインタを宣言します:
int (*fp)(double);
これは、double
引数を取り、int
を返す関数を指している必要があります。
func2
引数はありませんが、それでも私が書くとき:
fp = func2;
fp(2);
(2
は任意の数です)、func2`は正しく呼び出されます。
何故ですか?関数ポインタに対して宣言するパラメータの数に意味はありませんか?
はい、意味があります。 Cでは(ただし、C++ではnot)、空の括弧のセットで宣言された関数は、nspecifiedの数のパラメーターを受け取ることを意味します。これを行うと、コンパイラが引数の数とタイプをチェックできなくなります。これは、C言語がANSIおよびISOによって標準化される前からの遺物です。
適切な数とタイプの引数を使用して関数を呼び出さないと、未定義の動作になります。代わりに、void
のパラメーターリストを使用してゼロパラメーターを取るように関数を明示的に宣言すると、間違ったタイプの関数ポインターを割り当てると、コンパイラーは警告を出します。
int func1(); // declare function taking unspecified parameters
int func2(void); // declare function taking zero parameters
...
// No warning, since parameters are potentially compatible; calling will lead
// to undefined behavior
int (*fp1)(double) = func1;
...
// warning: assignment from incompatible pointer type
int (*fp2)(double) = func2;