diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-07-17 17:13:14 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-07-17 17:13:14 +0200 |
commit | c8591470d475f90e000cce7c5eb9fd0ab126a066 (patch) | |
tree | 931b90cd810cc0f5e577f26ff993c5a9222be7ea | |
parent | 9e457844f544793ab2b727351fca0805ddc0c20a (diff) | |
download | glibmm-c8591470d475f90e000cce7c5eb9fd0ab126a066.tar.gz |
Avoid compiler warnings from function pointer conversions
gcc8 -Wextra prints a warning when reinterpret_cast is used for conversion
between different types of function pointers. Avoid that by adding
Glib::bitwise_equivalent_cast<>() with a union with members of
the two types of function pointers.
* glib/src/optiongroup.ccg: Use Glib::bitwise_equivalent_cast<>() to convert
from a function pointer to void*.
See https://github.com/libsigcplusplus/libsigcplusplus/issues/1
-rw-r--r-- | gio/giomm/socketsource.cc | 5 | ||||
-rw-r--r-- | glib/glibmm/main.cc | 7 | ||||
-rw-r--r-- | glib/glibmm/utility.h | 19 | ||||
-rw-r--r-- | glib/src/optiongroup.ccg | 7 | ||||
-rw-r--r-- | tests/glibmm_vector/main.cc | 4 |
5 files changed, 29 insertions, 13 deletions
diff --git a/gio/giomm/socketsource.cc b/gio/giomm/socketsource.cc index af1e9740..934ca004 100644 --- a/gio/giomm/socketsource.cc +++ b/gio/giomm/socketsource.cc @@ -73,7 +73,8 @@ SignalSocket::connect(const sigc::slot<bool, Glib::IOCondition>& slot, GSource* const source = g_socket_create_source(socket->gobj(), (GIOCondition)condition, Glib::unwrap(cancellable)); return Glib::Source::attach_signal_source( - slot, priority, source, context_, (GSourceFunc)&giomm_signalsocket_callback); + slot, priority, source, context_, + Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_signalsocket_callback)); } SignalSocket @@ -96,7 +97,7 @@ SocketSource::SocketSource(const Glib::RefPtr<Socket>& socket, Glib::IOCondition const Glib::RefPtr<Cancellable>& cancellable) : IOSource( g_socket_create_source(socket->gobj(), (GIOCondition)condition, Glib::unwrap(cancellable)), - (GSourceFunc)&giomm_socketsource_callback) + Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_socketsource_callback)) { } diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc index 30a294c4..ff609a43 100644 --- a/glib/glibmm/main.cc +++ b/glib/glibmm/main.cc @@ -27,6 +27,7 @@ #include <glibmm/exceptionhandler.h> #include <glibmm/wrap.h> #include <glibmm/iochannel.h> +#include <glibmm/utility.h> #include <algorithm> #include <map> // Needed until the next ABI break. @@ -540,8 +541,8 @@ SignalChildWatch::connect(const sigc::slot<void, GPid, int>& slot, GPid pid, int if (priority != G_PRIORITY_DEFAULT) g_source_set_priority(source, priority); - g_source_set_callback(source, (GSourceFunc)&glibmm_child_watch_callback, conn_node, - &SourceConnectionNode::destroy_notify_callback); + g_source_set_callback(source, Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_child_watch_callback), + conn_node, &SourceConnectionNode::destroy_notify_callback); conn_node->install(source); g_source_attach(source, context_); @@ -1309,7 +1310,7 @@ IOSource::IOSource(PollFD::fd_t fd, IOCondition condition) : poll_fd_(fd, condit IOSource::IOSource(const Glib::RefPtr<IOChannel>& channel, IOCondition condition) : Source(g_io_create_watch(channel->gobj(), (GIOCondition)condition), - (GSourceFunc)&glibmm_iosource_callback) + Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_iosource_callback)) { } diff --git a/glib/glibmm/utility.h b/glib/glibmm/utility.h index eaf4c15a..39c74a9f 100644 --- a/glib/glibmm/utility.h +++ b/glib/glibmm/utility.h @@ -158,6 +158,25 @@ destroy_notify_delete(void* data) delete static_cast<T*>(data); } +// Conversion between different types of function pointers with +// reinterpret_cast can make gcc8 print a warning. +// https://github.com/libsigcplusplus/libsigcplusplus/issues/1 +/** Returns the supplied bit pattern, interpreted as another type. + * + * When reinterpret_cast causes a compiler warning or error, this function + * may work. Intended mainly for conversion between different types of pointers. + */ +template <typename T_out, typename T_in> +inline T_out bitwise_equivalent_cast(T_in in) +{ + union { + T_in in; + T_out out; + } u; + u.in = in; + return u.out; +} + } // namespace Glib #endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/glib/src/optiongroup.ccg b/glib/src/optiongroup.ccg index 95177ce4..483e8354 100644 --- a/glib/src/optiongroup.ccg +++ b/glib/src/optiongroup.ccg @@ -571,12 +571,7 @@ OptionGroup::CppOptionEntry::allocate_c_arg() case G_OPTION_ARG_CALLBACK: { // The C arg pointer is a function pointer, cast to void*. - union { - void* dp; - GOptionArgFunc fp; - } u; - u.fp = &OptionGroup::option_arg_callback; - carg_ = u.dp; + carg_ = Glib::bitwise_equivalent_cast<void*>(&OptionGroup::option_arg_callback); // With all compiler warnings turned on and a high optimization level // it's difficult to cast a function pointer to a void*. See bug 589197. diff --git a/tests/glibmm_vector/main.cc b/tests/glibmm_vector/main.cc index 31138cf0..dd83553e 100644 --- a/tests/glibmm_vector/main.cc +++ b/tests/glibmm_vector/main.cc @@ -198,12 +198,12 @@ public: { if (glist_) { - g_list_foreach(glist_, reinterpret_cast<GFunc>(g_object_unref), nullptr); + g_list_foreach(glist_, Glib::bitwise_equivalent_cast<GFunc>(g_object_unref), nullptr); g_list_free(glist_); } if (gslist_) { - g_slist_foreach(gslist_, reinterpret_cast<GFunc>(g_object_unref), nullptr); + g_slist_foreach(gslist_, Glib::bitwise_equivalent_cast<GFunc>(g_object_unref), nullptr); g_slist_free(gslist_); } if (garray_) |