Skip to content

Commit ecfa7c2

Browse files
committed
slot, signal: 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 sigc::internal::bitwise_equivalent_cast<>() with a union with members of the two types of function pointers. Fixes #1
1 parent 1aabb89 commit ecfa7c2

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

sigc++/functors/slot.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,25 @@ namespace sigc
3333
namespace internal
3434
{
3535

36+
// Conversion between different types of function pointers with
37+
// reinterpret_cast can make gcc8 print a warning.
38+
// https://github.com/libsigcplusplus/libsigcplusplus/issues/1
39+
/** Returns the supplied bit pattern, interpreted as another type.
40+
*
41+
* When reinterpret_cast causes a compiler warning or error, this function
42+
* may work. Intended mainly for conversion between different types of pointers.
43+
*/
44+
template <typename out_type, typename in_type>
45+
inline out_type bitwise_equivalent_cast(in_type in)
46+
{
47+
union {
48+
in_type in;
49+
out_type out;
50+
} u;
51+
u.in = in;
52+
return u.out;
53+
}
54+
3655
/** A typed slot_rep.
3756
* A typed slot_rep holds a functor that can be invoked from
3857
* slot::operator()(). visit_each() is used to visit the functor's
@@ -134,7 +153,7 @@ struct slot_call
134153
/** Forms a function pointer from call_it().
135154
* @return A function pointer formed from call_it().
136155
*/
137-
static hook address() { return reinterpret_cast<hook>(&call_it); }
156+
static hook address() { return bitwise_equivalent_cast<hook>(&call_it); }
138157
};
139158

140159
} /* namespace internal */
@@ -192,7 +211,7 @@ class slot<T_return(T_arg...)> : public slot_base
192211
inline T_return operator()(type_trait_take_t<T_arg>... a) const
193212
{
194213
if (!empty() && !blocked()) {
195-
return std::invoke(reinterpret_cast<call_type>(slot_base::rep_->call_), slot_base::rep_, a...);
214+
return std::invoke(internal::bitwise_equivalent_cast<call_type>(slot_base::rep_->call_), slot_base::rep_, a...);
196215
}
197216

198217
return T_return();

sigc++/signal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,12 @@ struct signal_emit<T_return, void, T_arg...>
322322
return T_return();
323323
}
324324

325-
r_ = (reinterpret_cast<call_type>(it->rep_->call_))(it->rep_, a...);
325+
r_ = (bitwise_equivalent_cast<call_type>(it->rep_->call_))(it->rep_, a...);
326326
for (++it; it != slots.end(); ++it)
327327
{
328328
if (it->empty() || it->blocked())
329329
continue;
330-
r_ = (reinterpret_cast<call_type>(it->rep_->call_))(it->rep_, a...);
330+
r_ = (bitwise_equivalent_cast<call_type>(it->rep_->call_))(it->rep_, a...);
331331
}
332332
}
333333

@@ -365,7 +365,7 @@ struct signal_emit<void, void, T_arg...>
365365
if (slot.empty() || slot.blocked())
366366
continue;
367367

368-
(reinterpret_cast<call_type>(slot.rep_->call_))(slot.rep_, a...);
368+
(bitwise_equivalent_cast<call_type>(slot.rep_->call_))(slot.rep_, a...);
369369
}
370370
}
371371
};

0 commit comments

Comments
 (0)