void *
標準では、関数へのポインターと関数へのポインターの間の変換は許可されていません。
6.3.2.3:8 あるタイプの関数へのポインターは、別のタイプの関数へのポインターに変換され、再び元に戻される場合があります。結果は元のポインタと等しくなります。変換されたポインターを使用して、ポイント先の型と互換性のない型を持つ関数を呼び出す場合、動作は未定義です。
glib/gtk には、この規則を破る関数がいくつかあります。例を次に示します。g_signal_handlers_block_by_func
a で大文字に変換する典型的な例GtkEntry
:
void
insert_text_handler (GtkEditable *editable,
const gchar *text,
gint length,
gint *position,
gpointer data)
{
gchar *result = g_utf8_strup (text, length);
g_signal_handlers_block_by_func (editable,
(gpointer) insert_text_handler, data);
gtk_editable_insert_text (editable, result, length, position);
g_signal_handlers_unblock_by_func (editable,
(gpointer) insert_text_handler, data);
g_signal_stop_emission_by_name (editable, "insert_text");
g_free (result);
}
gpointer
typedef
forvoid *
であり、次g_signal_handlers_unblock_by_func
を使用して実装されgpointer
ます。
guint g_signal_handlers_block_matched(gpointer instance,
GSignalMatchType mask,
guint signal_id,
GQuark detail,
GClosure *closure,
gpointer func,
gpointer data);
#define g_signal_handlers_block_by_func(instance, func, data) \
g_signal_handlers_block_matched((instance), \
(GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \
0, 0, NULL, (func), (data))
したがって、 を使用してこのコードをコンパイルする-std=c99
と、次の警告が表示されます。
src/client/gui.c: In function ‘insert_text_handler’:
src/client/gui.c:474:45: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
g_signal_handlers_block_by_func(editable, (gpointer)insert_text_handler, data);
そして、コンパイラを沈黙させるために私が見つけることができる唯一の方法は、次を使用すること__extension__
です:
__extension__ g_signal_handlers_block_by_func (editable, (gpointer)insert_text_handler, data);
長いプリアンブルで申し訳ありませんが、ご覧のとおり、glib / gtk は gcc 拡張機能を使用しており、シグナル ハンドラーを使用-pedantic
するプログラムをモードで (警告なしで)コンパイルする方法はありません。gtk
私の質問は:
-std=c99
と組み合わせて使用できますか、__extension__
または強制的に使用でき-std=gnu99
ますか?
言い換えれば、__extension__
拡張機能を使用してコンパイルすることを意味する (強制する) か、コンパイラを黙らせるための単なる指示であり、私のプログラムは未定義の動作の下で動作していますか?