Commit 6bc4f4e2 authored by Kjell Ahlstedt's avatar Kjell Ahlstedt

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
parent d3ca7e5e
......@@ -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
......@@ -104,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)),
(GSourceFunc)&giomm_socketsource_callback)
Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_socketsource_callback))
{
}
......@@ -112,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)),
(GSourceFunc)&giomm_socketsource_callback)
Glib::bitwise_equivalent_cast<GSourceFunc>(&giomm_socketsource_callback))
{
}
......
......@@ -18,6 +18,7 @@
#include <glibmm/exceptionhandler.h>
#include <glibmm/wrap.h>
#include <glibmm/iochannel.h>
#include <glibmm/utility.h>
#include <algorithm>
namespace
......@@ -507,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, (GSourceFunc)&glibmm_child_watch_callback,
g_source_set_callback(source, Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_child_watch_callback),
conn_node,
&glibmm_source_destroy_notify_callback);
......@@ -1231,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),
(GSourceFunc)&glibmm_iosource_callback)
Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_iosource_callback))
{
}
IOSource::IOSource(GIOChannel* channel, IOCondition condition)
: Source(g_io_create_watch(channel, (GIOCondition)condition),
(GSourceFunc)&glibmm_iosource_callback)
Glib::bitwise_equivalent_cast<GSourceFunc>(&glibmm_iosource_callback))
{
}
......
......@@ -93,6 +93,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 */
......
......@@ -552,12 +552,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.
......
......@@ -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;
......
......@@ -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_)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment