Add G_SOURCE_FUNC cast macro which suppresses -Wcast-function-type

This is the workaround suggested by
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wcast-function-type

This warning is not enabled by default during the GLib build, but
applications may want to opt into it.
This commit is contained in:
Will Thompson 2018-06-08 13:29:42 +01:00
parent aa44ece684
commit 039fa6897b
No known key found for this signature in database
GPG Key ID: 3422DC0D7AD482A7
4 changed files with 40 additions and 2 deletions

View File

@ -621,6 +621,7 @@ g_source_set_name_by_id
g_source_get_context
g_source_set_callback
GSourceFunc
G_SOURCE_FUNC
g_source_set_callback_indirect
g_source_set_ready_time
g_source_get_ready_time

View File

@ -1628,7 +1628,8 @@ g_source_set_callback_indirect (GSource *source,
*
* The exact type of @func depends on the type of source; ie. you
* should not count on @func being called with @data as its first
* parameter.
* parameter. Cast @func with G_SOURCE_FUNC() to avoid warnings about
* incompatible function types.
*
* See [memory management of sources][mainloop-memory-management] for details
* on how to handle memory management of @data.

View File

@ -163,11 +163,33 @@ typedef struct _GSourceFuncs GSourceFuncs;
* Specifies the type of function passed to g_timeout_add(),
* g_timeout_add_full(), g_idle_add(), and g_idle_add_full().
*
* When calling g_source_set_callback(), you may need to cast a function of a
* different type to this type. Use G_SOURCE_FUNC() to avoid warnings about
* incompatible function types.
*
* Returns: %FALSE if the source should be removed. #G_SOURCE_CONTINUE and
* #G_SOURCE_REMOVE are more memorable names for the return value.
*/
typedef gboolean (*GSourceFunc) (gpointer user_data);
/**
* G_SOURCE_FUNC:
* @f: a function pointer.
*
* Cast a function pointer to a #GSourceFunc, suppressing warnings from GCC 8
* onwards with `-Wextra` or `-Wcast-function-type` enabled about the function
* types being incompatible.
*
* For example, the correct type of callback for a source created by
* g_child_watch_source_new() is #GChildWatchFunc, which accepts more arguments
* than #GSourceFunc. Casting the function with `(GSourceFunc)` to call
* g_source_set_callback() will trigger a warning, even though it will be cast
* back to the correct type before it is called by the source.
*
* Since: 2.58
*/
#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f))
/**
* GChildWatchFunc:
* @pid: the process id of the child process

View File

@ -1306,7 +1306,21 @@ test_unix_fd_source (void)
out = in = FALSE;
out_source = g_unix_fd_source_new (fds[1], G_IO_OUT);
g_source_set_callback (out_source, (GSourceFunc) flag_bool, &out, NULL);
/* -Wcast-function-type complains about casting 'flag_bool' to GSourceFunc.
* GCC has no way of knowing that it will be cast back to GUnixFDSourceFunc
* before being called. Although GLib itself is not compiled with
* -Wcast-function-type, applications that use GLib may well be (since
* -Wextra includes it), so we provide a G_SOURCE_FUNC() macro to suppress
* the warning. We check that it works here.
*/
#if G_GNUC_CHECK_VERSION(8, 0)
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wcast-function-type"
#endif
g_source_set_callback (out_source, G_SOURCE_FUNC (flag_bool), &out, NULL);
#if G_GNUC_CHECK_VERSION(8, 0)
#pragma GCC diagnostic pop
#endif
g_source_attach (out_source, NULL);
assert_main_context_state (1,
fds[1], G_IO_OUT, 0);