[glibmm] Avoid compiler warnings from function pointer conversions



commit fa85bd1161d5d914095d1a3f9b620da294c9af79
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Fri Jul 13 18:59:01 2018 +0200

    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 instead using
    a union with members of the two types of function pointers.
    
    See https://github.com/libsigcplusplus/libsigcplusplus/issues/1

 gio/giomm/socketsource.cc         | 26 ++++++++++++++++++++++----
 glib/glibmm/main.cc               | 26 +++++++++++++++++++++-----
 tests/giomm_stream_vfuncs/main.cc |  2 +-
 tests/glibmm_vector/main.cc       | 13 +++++++++++--
 4 files changed, 55 insertions(+), 12 deletions(-)
---
diff --git a/gio/giomm/socketsource.cc b/gio/giomm/socketsource.cc
index 76249134..24248c85 100644
--- a/gio/giomm/socketsource.cc
+++ b/gio/giomm/socketsource.cc
@@ -54,6 +54,19 @@ giomm_socketsource_callback(GSocket*, GIOCondition condition, void* user_data)
   return giomm_generic_socket_callback(slot, condition);
 }
 
+GSourceFunc giomm_socketsource_cb_as_gsourcefunc()
+{
+  // Conversion between different types of function pointers with
+  // reinterpret_cast can make gcc8 print a warning.
+  // https://github.com/libsigcplusplus/libsigcplusplus/issues/1
+  union {
+    GSourceFunc ps;
+    decltype(&giomm_socketsource_callback) pss;
+  } u;
+  u.pss = &giomm_socketsource_callback;
+  return u.ps;
+}
+
 } // anonymous namespace
 
 namespace Gio
@@ -72,8 +85,13 @@ 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);
+
+  union {
+    GSourceFunc ps;
+    decltype(&giomm_signalsocket_callback) pss;
+  } u;
+  u.pss = &giomm_signalsocket_callback;
+  return Glib::Source::attach_signal_source(slot, priority, source, context_, u.ps);
 }
 
 SignalSocket
@@ -104,7 +122,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)
+    giomm_socketsource_cb_as_gsourcefunc())
 {
 }
 
@@ -112,7 +130,7 @@ SocketSource::SocketSource(GSocket* socket, Glib::IOCondition condition,
   const Glib::RefPtr<Cancellable>& cancellable)
 : IOSource(
     g_socket_create_source(socket, (GIOCondition)condition, Glib::unwrap(cancellable)),
-    (GSourceFunc)&giomm_socketsource_callback)
+    giomm_socketsource_cb_as_gsourcefunc())
 {
 }
 
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 7edb8f41..eec2b1cc 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -242,6 +242,19 @@ glibmm_iosource_callback(GIOChannel*, GIOCondition condition, void* data)
   return 0;
 }
 
+GSourceFunc glibmm_iosource_cb_as_gsourcefunc()
+{
+  // Conversion between different types of function pointers with
+  // reinterpret_cast can make gcc8 print a warning.
+  // https://github.com/libsigcplusplus/libsigcplusplus/issues/1
+  union {
+    GSourceFunc ps;
+    decltype(&glibmm_iosource_callback) pios;
+  } u;
+  u.pios = &glibmm_iosource_callback;
+  return u.ps;
+}
+
 /* Only used by SignalChildWatch::connect().
  * These don't use Glib::Source, to avoid the unnecessary overhead
  * of a completely unused wrapper object.
@@ -507,9 +520,12 @@ 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,
-    &glibmm_source_destroy_notify_callback);
+  union {
+    GSourceFunc ps;
+    decltype(&glibmm_child_watch_callback) pcw;
+  } u;
+  u.pcw = &glibmm_child_watch_callback;
+  g_source_set_callback(source, u.ps, conn_node, &glibmm_source_destroy_notify_callback);
 
   conn_node->install(source);
   g_source_attach(source, context_);
@@ -1231,13 +1247,13 @@ 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)
+    glibmm_iosource_cb_as_gsourcefunc())
 {
 }
 
 IOSource::IOSource(GIOChannel* channel, IOCondition condition)
 : Source(g_io_create_watch(channel, (GIOCondition)condition),
-    (GSourceFunc)&glibmm_iosource_callback)
+    glibmm_iosource_cb_as_gsourcefunc())
 {
 }
 
diff --git a/tests/giomm_stream_vfuncs/main.cc b/tests/giomm_stream_vfuncs/main.cc
index df1cde20..ad42e989 100644
--- a/tests/giomm_stream_vfuncs/main.cc
+++ b/tests/giomm_stream_vfuncs/main.cc
@@ -160,7 +160,7 @@ int main(int, char**)
       return EXIT_FAILURE;
     }
   }
-  catch (Gio::Error e)
+  catch (const Gio::Error& e)
   {
     std::cout << "Gio error: " << e.what() << std::endl;
     return EXIT_FAILURE;
diff --git a/tests/glibmm_vector/main.cc b/tests/glibmm_vector/main.cc
index 31138cf0..0f039356 100644
--- a/tests/glibmm_vector/main.cc
+++ b/tests/glibmm_vector/main.cc
@@ -196,14 +196,23 @@ public:
 
   ~Cache()
   {
+    // Conversion between different types of function pointers with
+    // reinterpret_cast can make gcc8 print a warning.
+    // https://github.com/libsigcplusplus/libsigcplusplus/issues/1
+    union {
+      GFunc pf;
+      decltype(&g_object_unref) pou;
+    } u;
+    u.pou = &g_object_unref;
+
     if (glist_)
     {
-      g_list_foreach(glist_, reinterpret_cast<GFunc>(g_object_unref), nullptr);
+      g_list_foreach(glist_, u.pf, nullptr);
       g_list_free(glist_);
     }
     if (gslist_)
     {
-      g_slist_foreach(gslist_, reinterpret_cast<GFunc>(g_object_unref), nullptr);
+      g_slist_foreach(gslist_, u.pf, nullptr);
       g_slist_free(gslist_);
     }
     if (garray_)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]