summaryrefslogtreecommitdiff
path: root/sigc++
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2018-08-29 12:44:26 +0200
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2018-08-29 12:44:26 +0200
commit5ddad762ab2f28e6d2836490df0f9862ecae7e1f (patch)
tree2366007fffe11709a435541e81ca81d997424cca /sigc++
parentb8e50985813bbd04b2e1be6a78221e5fc81d0124 (diff)
downloadsigc++-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.h28
-rw-r--r--sigc++/signal.h6
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...);
}
}
};