summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2018-07-17 17:13:14 +0200
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2018-07-17 17:13:14 +0200
commitc8591470d475f90e000cce7c5eb9fd0ab126a066 (patch)
tree931b90cd810cc0f5e577f26ff993c5a9222be7ea
parent9e457844f544793ab2b727351fca0805ddc0c20a (diff)
downloadglibmm-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.cc5
-rw-r--r--glib/glibmm/main.cc7
-rw-r--r--glib/glibmm/utility.h19
-rw-r--r--glib/src/optiongroup.ccg7
-rw-r--r--tests/glibmm_vector/main.cc4
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_)