The standard doesn't allow to convert between pointers to void *
and pointers to functions:
6.3.2.3:8 A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.
There are several functions in glib/gtk breaking this rule, an example is g_signal_handlers_block_by_func
A typical example converting to uppercase in 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
is a typedef
for void *
and g_signal_handlers_unblock_by_func
is implemented using 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))
Thus, compiling this code using -std=c99
gives the following warning:
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);
And the only way I can find to silence the compiler is using __extension__
:
__extension__ g_signal_handlers_block_by_func (editable, (gpointer)insert_text_handler, data);
Sorry for such long preamble but as you can see glib / gtk is using gcc extensions and there is no way to compile in -pedantic
mode (without warnings) a gtk
program using signal handlers.
My question is:
Can we use -std=c99
in conjunction with __extension__
or we are forced to use -std=gnu99
?
In other words, does __extension__
implies (forces) compiling with extensions or is just an instruction to silence the compiler and my program is working under undefined behaviour?