diff options
-rw-r--r-- | gio/giomm/socketsource.cc | 6 | ||||
-rw-r--r-- | glib/glibmm/main.cc | 6 | ||||
-rw-r--r-- | glib/glibmm/utility.h | 23 | ||||
-rw-r--r-- | glib/src/optiongroup.ccg | 28 | ||||
-rw-r--r-- | tests/glibmm_vector/main.cc | 4 |
5 files changed, 34 insertions, 33 deletions
diff --git a/gio/giomm/socketsource.cc b/gio/giomm/socketsource.cc index 4485a996..e46af5dd 100644 --- a/gio/giomm/socketsource.cc +++ b/gio/giomm/socketsource.cc @@ -74,7 +74,7 @@ SignalSocket::connect(const sigc::slot<bool(Glib::IOCondition)>& slot, g_socket_create_source(socket->gobj(), (GIOCondition)condition, Glib::unwrap(cancellable)); return Glib::Source::attach_signal_source( slot, priority, source, context_, - Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_signalsocket_callback)); + Glib::function_pointer_cast<GSourceFunc>(&giomm_signalsocket_callback)); } SignalSocket @@ -105,7 +105,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)), - Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_socketsource_callback)) + Glib::function_pointer_cast<GSourceFunc>(&giomm_socketsource_callback)) { } @@ -113,7 +113,7 @@ SocketSource::SocketSource(GSocket* socket, Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable) : IOSource( g_socket_create_source(socket, (GIOCondition)condition, Glib::unwrap(cancellable)), - Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_socketsource_callback)) + Glib::function_pointer_cast<GSourceFunc>(&giomm_socketsource_callback)) { } diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc index 15200099..e4095405 100644 --- a/glib/glibmm/main.cc +++ b/glib/glibmm/main.cc @@ -508,7 +508,7 @@ 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, Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_child_watch_callback), + g_source_set_callback(source, Glib::function_pointer_cast<GSourceFunc>(&glibmm_child_watch_callback), conn_node, &glibmm_source_destroy_notify_callback); @@ -1232,13 +1232,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), - Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_iosource_callback)) + Glib::function_pointer_cast<GSourceFunc>(&glibmm_iosource_callback)) { } IOSource::IOSource(GIOChannel* channel, IOCondition condition) : Source(g_io_create_watch(channel, (GIOCondition)condition), - Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_iosource_callback)) + Glib::function_pointer_cast<GSourceFunc>(&glibmm_iosource_callback)) { } diff --git a/glib/glibmm/utility.h b/glib/glibmm/utility.h index da23272c..6c7378af 100644 --- a/glib/glibmm/utility.h +++ b/glib/glibmm/utility.h @@ -96,20 +96,23 @@ destroy_notify_delete(void* 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. +// https://github.com/libsigcplusplus/libsigcplusplus/issues/8 +/** Returns the supplied function pointer, cast to a pointer to another function type. * - * When reinterpret_cast causes a compiler warning or error, this function - * may work. Intended mainly for conversion between different types of pointers. + * When a single reinterpret_cast between function pointer types causes a + * compiler warning or error, this function may work. + * + * Qualify calls with namespace names: sigc::internal::function_pointer_cast<>(). + * If you don't, indirect calls from another library that also contains a + * function_pointer_cast<>() (perhaps glibmm), can be ambiguous due to ADL + * (argument-dependent lookup). */ template <typename T_out, typename T_in> -inline T_out bitwise_equivalent_cast(T_in in) +inline T_out function_pointer_cast(T_in in) { - union { - T_in in; - T_out out; - } u; - u.in = in; - return u.out; + // The double reinterpret_cast suppresses a warning from gcc8 with the + // -Wcast-function-type option. + return reinterpret_cast<T_out>(reinterpret_cast<void (*)()>(in)); } } // namespace Glib diff --git a/glib/src/optiongroup.ccg b/glib/src/optiongroup.ccg index b14d7b31..ee9b7bfe 100644 --- a/glib/src/optiongroup.ccg +++ b/glib/src/optiongroup.ccg @@ -552,22 +552,20 @@ OptionGroup::CppOptionEntry::allocate_c_arg() case G_OPTION_ARG_CALLBACK: { // The C arg pointer is a function pointer, cast to void*. - 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. - // A few results with g++ 4.4.5 with the flags -pedantic -O2 -Werror: - // - // carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); - // error: ISO C++ forbids casting between pointer-to-function and pointer-to-object - // - // *reinterpret_cast<GOptionArgFunc*>(&carg_) = &OptionGroup::option_arg_callback; - // *(OptionArgFunc*)&carg_ = &OptionGroup::option_arg_callback; - // error: dereferencing type-punned pointer will break strict-aliasing rules // - // If any compiler dislikes the union, the following code is worth testing: - // carg_ = reinterpret_cast<void*>( - // reinterpret_cast<unsigned long>(&OptionGroup::option_arg_callback)); + // carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); + // or + // union { + // void* dp; + // GOptionArgFunc fp; + // } u; + // u.fp = &OptionGroup::option_arg_callback; + // carg_ = u.dp; + // ? See + // https://bugzilla.gnome.org/show_bug.cgi?id=589197 + // https://github.com/libsigcplusplus/libsigcplusplus/issues/1 + // https://github.com/libsigcplusplus/libsigcplusplus/issues/8 + carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); break; } diff --git a/tests/glibmm_vector/main.cc b/tests/glibmm_vector/main.cc index dd83553e..a3719532 100644 --- a/tests/glibmm_vector/main.cc +++ b/tests/glibmm_vector/main.cc @@ -198,12 +198,12 @@ public: { if (glist_) { - g_list_foreach(glist_, Glib::bitwise_equivalent_cast<GFunc>(g_object_unref), nullptr); + g_list_foreach(glist_, Glib::function_pointer_cast<GFunc>(g_object_unref), nullptr); g_list_free(glist_); } if (gslist_) { - g_slist_foreach(gslist_, Glib::bitwise_equivalent_cast<GFunc>(g_object_unref), nullptr); + g_slist_foreach(gslist_, Glib::function_pointer_cast<GFunc>(g_object_unref), nullptr); g_slist_free(gslist_); } if (garray_) |