diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-08-29 12:39:25 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-08-29 12:39:25 +0200 |
commit | a5607f88a1024c5a919fb866a20a14f48361279b (patch) | |
tree | 17e09fc0a505069a9e44503b4e59c6d0d34174d3 | |
parent | 8bed5b9a9419b13cf928ddaf9b237962023a6640 (diff) | |
download | sigc++-a5607f88a1024c5a919fb866a20a14f48361279b.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
-rw-r--r-- | sigc++/functors/macros/slot.h.m4 | 34 | ||||
-rw-r--r-- | sigc++/macros/signal.h.m4 | 14 |
2 files changed, 23 insertions, 25 deletions
diff --git a/sigc++/functors/macros/slot.h.m4 b/sigc++/functors/macros/slot.h.m4 index dee0b13..f22dba2 100644 --- a/sigc++/functors/macros/slot.h.m4 +++ b/sigc++/functors/macros/slot.h.m4 @@ -63,7 +63,7 @@ FOR(1, $1,[ inline T_return operator()(LOOP(arg%1_type_ _A_a%1, $1)) const { if (!empty() && !blocked()) - return (sigc::internal::bitwise_equivalent_cast<call_type>(slot_base::rep_->call_))(LIST(slot_base::rep_, LOOP(_A_a%1, $1))); + return (sigc::internal::function_pointer_cast<call_type>(slot_base::rep_->call_))(LIST(slot_base::rep_, LOOP(_A_a%1, $1))); return T_return(); } @@ -355,7 +355,7 @@ ifelse($1,0,[ * @return A function pointer formed from call_it(). */ static hook address() - { return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); } + { return sigc::internal::function_pointer_cast<hook>(&call_it); } }; ]) @@ -381,25 +381,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. @@ -507,7 +505,7 @@ struct slot_call * @return A function pointer formed from call_it(). */ static hook address() - { return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); } + { return sigc::internal::function_pointer_cast<hook>(&call_it); } }; /** Abstracts functor execution. @@ -539,7 +537,7 @@ struct slot_call<T_functor, T_return> * @return A function pointer formed from call_it(). */ static hook address() - { return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); } + { return sigc::internal::function_pointer_cast<hook>(&call_it); } }; } /* namespace internal */ @@ -599,7 +597,7 @@ public: inline T_return operator()(type_trait_take_t<T_arg>... _A_a) const { if (!empty() && !blocked()) - return (sigc::internal::bitwise_equivalent_cast<call_type>(slot_base::rep_->call_))(slot_base::rep_, _A_a...); + return (sigc::internal::function_pointer_cast<call_type>(slot_base::rep_->call_))(slot_base::rep_, _A_a...); return T_return(); } diff --git a/sigc++/macros/signal.h.m4 b/sigc++/macros/signal.h.m4 index 00040f4..9489256 100644 --- a/sigc++/macros/signal.h.m4 +++ b/sigc++/macros/signal.h.m4 @@ -51,7 +51,7 @@ ifelse($1,0,[dnl * @return The slot's return value. */ T_return operator()(const slot_type& _A_slot) const - { return (sigc::internal::bitwise_equivalent_cast<typename slot_type::call_type>(_A_slot.rep_->call_))(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); } + { return (sigc::internal::function_pointer_cast<typename slot_type::call_type>(_A_slot.rep_->call_))(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); } dnl T_return operator()(const slot_type& _A_slot) const dnl { return _A_slot(LOOP(_A_a%1_, $1)); } @@ -150,12 +150,12 @@ FOR(1, $1,[ if (it == slots.end()) return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows: - r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); for (++it; it != slots.end(); ++it) { if (it->empty() || it->blocked()) continue; - r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); } } @@ -201,12 +201,12 @@ FOR(1, $1,[ if (it == reverse_iterator_type(slots.begin())) return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows: - r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); for (++it; it != reverse_iterator_type(slots.begin()); ++it) { if (it->empty() || it->blocked()) continue; - r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); } } @@ -247,7 +247,7 @@ FOR(1, $1,[ { if (slot.empty() || slot.blocked()) continue; - (sigc::internal::bitwise_equivalent_cast<call_type>(slot.rep_->call_))(LIST(slot.rep_, LOOP(_A_a%1, $1))); + (sigc::internal::function_pointer_cast<call_type>(slot.rep_->call_))(LIST(slot.rep_, LOOP(_A_a%1, $1))); } } @@ -278,7 +278,7 @@ FOR(1, $1,[ { if (it->empty() || it->blocked()) continue; - (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); } } _DEPRECATE_IFDEF_END |