diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-08-29 12:44:26 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-08-29 12:44:26 +0200 |
commit | 5ddad762ab2f28e6d2836490df0f9862ecae7e1f (patch) | |
tree | 2366007fffe11709a435541e81ca81d997424cca /sigc++ | |
parent | b8e50985813bbd04b2e1be6a78221e5fc81d0124 (diff) | |
download | sigc++-5ddad762ab2f28e6d2836490df0f9862ecae7e1f.tar.gz |
slot, signal: Avoid compiler warnings from function pointer conversions
gcc8 -Wextra prints a warning when a single reinterpret_cast is used for
conversion between different types of function pointers. The previous fix
with a union in sigc::internal::bitwise_equivalent_cast<>() is not standard
C++. Rename the function to function_pointer_cast<>(), and use two
reinterpret_casts as recommended in gcc's documentation.
Fixes #8
Diffstat (limited to 'sigc++')
-rw-r--r-- | sigc++/functors/slot.h | 28 | ||||
-rw-r--r-- | sigc++/signal.h | 6 |
2 files changed, 16 insertions, 18 deletions
diff --git a/sigc++/functors/slot.h b/sigc++/functors/slot.h index 08996bd..8b308db 100644 --- a/sigc++/functors/slot.h +++ b/sigc++/functors/slot.h @@ -36,25 +36,23 @@ namespace internal // 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::bitwise_equivalent_cast<>(). + * Qualify calls with namespace names: sigc::internal::function_pointer_cast<>(). * If you don't, indirect calls from another library that also contains a - * bitwise_equivalent_cast<>() (perhaps glibmm), can be ambiguous due to ADL + * function_pointer_cast<>() (perhaps glibmm), can be ambiguous due to ADL * (argument-dependent lookup). */ -template <typename out_type, typename in_type> -inline out_type bitwise_equivalent_cast(in_type in) +template <typename T_out, typename T_in> +inline T_out function_pointer_cast(T_in in) { - union { - in_type in; - out_type 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)); } /** A typed slot_rep. @@ -158,7 +156,7 @@ struct slot_call /** Forms a function pointer from call_it(). * @return A function pointer formed from call_it(). */ - static hook address() { return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); } + static hook address() { return sigc::internal::function_pointer_cast<hook>(&call_it); } }; } /* namespace internal */ @@ -216,7 +214,7 @@ public: inline T_return operator()(type_trait_take_t<T_arg>... a) const { if (!empty() && !blocked()) { - return std::invoke(sigc::internal::bitwise_equivalent_cast<call_type>(slot_base::rep_->call_), slot_base::rep_, a...); + return std::invoke(sigc::internal::function_pointer_cast<call_type>(slot_base::rep_->call_), slot_base::rep_, a...); } return T_return(); diff --git a/sigc++/signal.h b/sigc++/signal.h index 3ebc65c..95d97aa 100644 --- a/sigc++/signal.h +++ b/sigc++/signal.h @@ -322,12 +322,12 @@ public: return T_return(); } - r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(it->rep_, a...); + r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(it->rep_, a...); for (++it; it != slots.end(); ++it) { if (it->empty() || it->blocked()) continue; - r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(it->rep_, a...); + r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(it->rep_, a...); } } @@ -365,7 +365,7 @@ public: if (slot.empty() || slot.blocked()) continue; - (sigc::internal::bitwise_equivalent_cast<call_type>(slot.rep_->call_))(slot.rep_, a...); + (sigc::internal::function_pointer_cast<call_type>(slot.rep_->call_))(slot.rep_, a...); } } }; |