Cにおける関数ポインタは、関数のアドレスを格納する変数で、動的にどの関数を呼び出すかを選択することができます。関数ポインタの一般的な宣言:
// intを受け取り、intを返す関数ポインタ int (*f_ptr)(int);
ポインタの配列の場合:
int func1(int x) { return x + 1; } int func2(int x) { return x * 2; } int (*f_arr[2])(int) = { func1, func2 }; int result = f_arr[1](10); // 20を返す
関数ポインタを使って異なるシグネチャを持つ関数を呼び出すことは可能ですか?
よくある誤った回答: 「はい、キャストを使えば可能です。」
正しい回答: 技術的には動的な性質のため可能ですが、その行為はランタイムエラーや予測できない動作を引き起こします。なぜなら、異なる呼び出し規約と引数の結合が使用される関数が呼び出されるためです。
例:
void funcA(int x) { printf("A: %d ", x); } void funcB(float y) { printf("B: %f ", y); } void (*fptr)(int) = (void (*)(int)) funcB; fptr(5); // エラー: 不正なデータが渡される
物語
物語
物語
ファームウェアでは、関数ポインタの変更結果を確認していませんでした。不十分なハンドラ配列の初期化により、ヌルポインタ(NULL)が呼び出され、デバイスがユーザーに通知されることなくフリーズしました。