私は最近、GLibのいくつかのコードに関してこれとまったく同じ問題について尋ねました。(GLibはGNOMEプロジェクトのコアライブラリであり、Cで記述されています。)スロット「n」シグナルフレームワーク全体がそれに依存していると言われました。
コード全体を通して、タイプ(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;
result = compare_func (data1, data2, user_data);
return result;
}
ここで自分の目で確かめてくださいg_array_sort()
: http://git.gnome.org/browse/glib/tree/glib/garray.c
上記の答えは詳細であり、おそらく正しいです-もしあなたが標準委員会に座っている。アダムとヨハネスは、よく研究された回答を称賛するに値します。ただし、実際には、このコードは問題なく機能することがわかります。物議を醸す?はい。これを考慮してください:GLibは、多種多様なコンパイラ/リンカー/カーネルローダー(GCC / CLang / MSVC)を備えた多数のプラットフォーム(Linux / Solaris / Windows / OS X)でコンパイル/動作/テストします。基準は酷いものだと思います。
私はこれらの答えについて考えるのに少し時間を費やしました。これが私の結論です:
- コールバックライブラリを作成している場合、これは問題ない可能性があります。警告エンプター-自己責任で使用してください。
- そうでなければ、それをしないでください。
この応答を書いた後で深く考えてみると、Cコンパイラのコードがこれと同じトリックを使用していても驚かないでしょう。そして(ほとんど/すべて?)最新のCコンパイラはブートストラップされているので、これはトリックが安全であることを意味します。
調査するより重要な質問:誰かがこのトリックが機能しないプラットフォーム/コンパイラ/リンカー/ローダーを見つけることができますか?その1つの主要なブラウニーポイント。私はそれを嫌ういくつかの組み込みプロセッサ/システムがあるに違いない。ただし、デスクトップコンピューティング(およびおそらくモバイル/タブレット)の場合、このトリックはおそらくまだ機能します。