Skip to content

Commit c7dbcd5

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 instead using a union with members of the two types of function pointers. Fixes libsigcplusplus#1
1 parent 94c1f9a commit c7dbcd5

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

sigc++/functors/slot.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,18 @@ struct slot_call
134134
/** Forms a function pointer from call_it().
135135
* @return A function pointer formed from call_it().
136136
*/
137-
static hook address() { return reinterpret_cast<hook>(&call_it); }
137+
static hook address()
138+
{
139+
// Conversion between different types of function pointers with
140+
// reinterpret_cast can make gcc8 print a warning.
141+
// https://github.com/libsigcplusplus/libsigcplusplus/issues/1
142+
union {
143+
hook ph;
144+
decltype(&call_it) pc;
145+
} u;
146+
u.pc = &call_it;
147+
return u.ph;
148+
}
138149
};
139150

140151
} /* namespace internal */
@@ -191,8 +202,17 @@ class slot<T_return(T_arg...)> : public slot_base
191202
*/
192203
inline T_return operator()(type_trait_take_t<T_arg>... a) const
193204
{
194-
if (!empty() && !blocked()) {
195-
return std::invoke(reinterpret_cast<call_type>(slot_base::rep_->call_), slot_base::rep_, a...);
205+
if (!empty() && !blocked())
206+
{
207+
// Conversion between different types of function pointers with
208+
// reinterpret_cast can make gcc8 print a warning.
209+
// https://github.com/libsigcplusplus/libsigcplusplus/issues/1
210+
union {
211+
internal::hook ph;
212+
call_type pc;
213+
} u;
214+
u.ph = slot_base::rep_->call_;
215+
return std::invoke(u.pc, slot_base::rep_, a...);
196216
}
197217

198218
return T_return();

sigc++/signal.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,21 @@ 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+
// Conversion between different types of function pointers with
326+
// reinterpret_cast can make gcc8 print a warning.
327+
// https://github.com/libsigcplusplus/libsigcplusplus/issues/1
328+
union {
329+
internal::hook ph;
330+
call_type pc;
331+
} u;
332+
u.ph = it->rep_->call_;
333+
r_ = (u.pc)(it->rep_, a...);
326334
for (++it; it != slots.end(); ++it)
327335
{
328336
if (it->empty() || it->blocked())
329337
continue;
330-
r_ = (reinterpret_cast<call_type>(it->rep_->call_))(it->rep_, a...);
338+
u.ph = it->rep_->call_;
339+
r_ = (u.pc)(it->rep_, a...);
331340
}
332341
}
333342

@@ -360,12 +369,20 @@ struct signal_emit<void, void, T_arg...>
360369
signal_impl_holder exec(impl);
361370
const temp_slot_list slots(impl->slots_);
362371

372+
// Conversion between different types of function pointers with
373+
// reinterpret_cast can make gcc8 print a warning.
374+
// https://github.com/libsigcplusplus/libsigcplusplus/issues/1
375+
union {
376+
internal::hook ph;
377+
call_type pc;
378+
} u;
363379
for (const auto& slot : slots)
364380
{
365381
if (slot.empty() || slot.blocked())
366382
continue;
367383

368-
(reinterpret_cast<call_type>(slot.rep_->call_))(slot.rep_, a...);
384+
u.ph = slot.rep_->call_;
385+
(u.pc)(slot.rep_, a...);
369386
}
370387
}
371388
};

0 commit comments

Comments
 (0)