最近、GLib の一部のコードに関して、まったく同じ問題について質問しました。(GLib は GNOME プロジェクトのコア ライブラリであり、C で記述されています。) 私は、slots'n'signals フレームワーク全体が GLib に依存していると聞きました。
コード全体で、タイプ (1) から (2) へのキャストのインスタンスが多数あります。
typedef int (*CompareFunc) (const void *a,
const void *b)
typedef int (*CompareDataFunc) (const void *b,
const void *b,
void *user_data)
次のような呼び出しでチェーンスルーするのが一般的です。
int stuff_equal (GStuff *a,
GStuff *b,
CompareFunc compare_func)
{
return stuff_equal_with_data(a, b, (CompareDataFunc) compare_func, NULL);
}
int stuff_equal_with_data (GStuff *a,
GStuff *b,
CompareDataFunc compare_func,
void *user_data)
{
int result;
/* do some work here */
result = compare_func (data1, data2, user_data);
return result;
}
ここで自分の目で確かめてくださいg_array_sort()
:http://git.gnome.org/browse/glib/tree/glib/garray.c
上記の回答は詳細であり、標準化委員会に参加している場合はおそらく正しいでしょう。Adam と Johannes のよく研究された回答は称賛に値します。ただし、実際には、このコードが問題なく機能することがわかります。物議を醸す?はい。これを考慮してください: GLib は、さまざまなコンパイラ/リンカー/カーネル ローダー (GCC/CLang/MSVC) を備えた多数のプラットフォーム (Linux/Solaris/Windows/OS X) でコンパイル/動作/テストします。基準はひどいものだと思います。
私はこれらの答えについてしばらく考えました。これが私の結論です:
- コールバック ライブラリを作成している場合は、これで問題ない可能性があります。警告 emptor -- 自己責任で使用してください。
- そうでなければ、それをしないでください。
この回答を書いた後でよく考えてみると、C コンパイラのコードがこれと同じトリックを使用していても驚かないでしょう。そして、(ほとんど/すべて?) 最新の C コンパイラはブートストラップされているため、これはトリックが安全であることを意味します。
調査すべきより重要な質問: このトリックが機能しないプラットフォーム/コンパイラ/リンカー/ローダーを誰かが見つけられますか? そのための主要なブラウニーポイント。それを好まない組み込みプロセッサ/システムがいくつかあるに違いありません。ただし、デスクトップ コンピューティング (およびおそらくモバイル/タブレット) の場合、このトリックはおそらくまだ機能します。