summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2018-08-29 12:39:25 +0200
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2018-08-29 12:39:25 +0200
commita5607f88a1024c5a919fb866a20a14f48361279b (patch)
tree17e09fc0a505069a9e44503b4e59c6d0d34174d3
parent8bed5b9a9419b13cf928ddaf9b237962023a6640 (diff)
downloadsigc++-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.m434
-rw-r--r--sigc++/macros/signal.h.m414
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