コールバック関数は、別の関数に引数として渡される関数のアドレスです。これにより、イベントハンドラー、ユーザーアルゴリズム、プラグインを実装できます。
コールバック関数の宣言:
typedef void (*callback_func_t)(int);
void process(callback_func_t cb) { // ... cb(42); // コールバックの呼び出し } void handler(int n) { printf("処理された数: %d ", n); } int main() { process(handler); return 0; }
アドバイス:
シグネチャが一致しない関数をコールバックとして渡すことはできますか?
よくある誤った回答: 「はい、明示的な型変換を宣言すればCは許可します。」
正しい回答: 形式的な型変換は可能ですが、そのような関数を呼び出すことは未定義の動作につながります — パラメータに無効な値が渡され、スタックが壊れる可能性があります。
危険の例:
typedef void (*cb_t)(int); void wrong_cb(double d) { printf("%f ", d); } void call(cb_t f) { f(123); } int main() { call((cb_t)wrong_cb); } // 危険: シグネチャが異なります
物語
物語
物語
クロスプラットフォームシステムを開発する際、著者はコールバック関数の呼び出し規約を誤って定義しました。これにより、あるOSでは問題が発生しませんでしたが、別のOSでCライブラリからコールバックを呼び出すとプログラムがクラッシュしました。