Skip to content

Commit a5607f8

Browse files
committed
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 libsigcplusplus#8
1 parent 8bed5b9 commit a5607f8

File tree

2 files changed

+23
-25
lines changed

2 files changed

+23
-25
lines changed

sigc++/functors/macros/slot.h.m4

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ FOR(1, $1,[
6363
inline T_return operator()(LOOP(arg%1_type_ _A_a%1, $1)) const
6464
{
6565
if (!empty() && !blocked())
66-
return (sigc::internal::bitwise_equivalent_cast<call_type>(slot_base::rep_->call_))(LIST(slot_base::rep_, LOOP(_A_a%1, $1)));
66+
return (sigc::internal::function_pointer_cast<call_type>(slot_base::rep_->call_))(LIST(slot_base::rep_, LOOP(_A_a%1, $1)));
6767
return T_return();
6868
}
6969
@@ -355,7 +355,7 @@ ifelse($1,0,[
355355
* @return A function pointer formed from call_it().
356356
*/
357357
static hook address()
358-
{ return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); }
358+
{ return sigc::internal::function_pointer_cast<hook>(&call_it); }
359359
};
360360
361361
])
@@ -381,25 +381,23 @@ namespace internal {
381381
// Conversion between different types of function pointers with
382382
// reinterpret_cast can make gcc8 print a warning.
383383
// https://github.com/libsigcplusplus/libsigcplusplus/issues/1
384-
/** Returns the supplied bit pattern, interpreted as another type.
384+
// https://github.com/libsigcplusplus/libsigcplusplus/issues/8
385+
/** Returns the supplied function pointer, cast to a pointer to another function type.
385386
*
386-
* When reinterpret_cast causes a compiler warning or error, this function
387-
* may work. Intended mainly for conversion between different types of pointers.
387+
* When a single reinterpret_cast between function pointer types causes a
388+
* compiler warning or error, this function may work.
388389
*
389-
* Qualify calls with namespace names: sigc::internal::bitwise_equivalent_cast<>().
390+
* Qualify calls with namespace names: sigc::internal::function_pointer_cast<>().
390391
* If you don't, indirect calls from another library that also contains a
391-
* bitwise_equivalent_cast<>() (perhaps glibmm), can be ambiguous due to ADL
392+
* function_pointer_cast<>() (perhaps glibmm), can be ambiguous due to ADL
392393
* (argument-dependent lookup).
393394
*/
394-
template <typename out_type, typename in_type>
395-
inline out_type bitwise_equivalent_cast(in_type in)
395+
template <typename T_out, typename T_in>
396+
inline T_out function_pointer_cast(T_in in)
396397
{
397-
union {
398-
in_type in;
399-
out_type out;
400-
} u;
401-
u.in = in;
402-
return u.out;
398+
// The double reinterpret_cast suppresses a warning from gcc8 with the
399+
// -Wcast-function-type option.
400+
return reinterpret_cast<T_out>(reinterpret_cast<void (*)()>(in));
403401
}
404402

405403
/** A typed slot_rep.
@@ -507,7 +505,7 @@ struct slot_call
507505
* @return A function pointer formed from call_it().
508506
*/
509507
static hook address()
510-
{ return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); }
508+
{ return sigc::internal::function_pointer_cast<hook>(&call_it); }
511509
};
512510

513511
/** Abstracts functor execution.
@@ -539,7 +537,7 @@ struct slot_call<T_functor, T_return>
539537
* @return A function pointer formed from call_it().
540538
*/
541539
static hook address()
542-
{ return sigc::internal::bitwise_equivalent_cast<hook>(&call_it); }
540+
{ return sigc::internal::function_pointer_cast<hook>(&call_it); }
543541
};
544542

545543
} /* namespace internal */
@@ -599,7 +597,7 @@ public:
599597
inline T_return operator()(type_trait_take_t<T_arg>... _A_a) const
600598
{
601599
if (!empty() && !blocked())
602-
return (sigc::internal::bitwise_equivalent_cast<call_type>(slot_base::rep_->call_))(slot_base::rep_, _A_a...);
600+
return (sigc::internal::function_pointer_cast<call_type>(slot_base::rep_->call_))(slot_base::rep_, _A_a...);
603601
return T_return();
604602
}
605603

sigc++/macros/signal.h.m4

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ ifelse($1,0,[dnl
5151
* @return The slot's return value.
5252
*/
5353
T_return operator()(const slot_type& _A_slot) const
54-
{ return (sigc::internal::bitwise_equivalent_cast<typename slot_type::call_type>(_A_slot.rep_->call_))(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); }
54+
{ return (sigc::internal::function_pointer_cast<typename slot_type::call_type>(_A_slot.rep_->call_))(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); }
5555
dnl T_return operator()(const slot_type& _A_slot) const
5656
dnl { return _A_slot(LOOP(_A_a%1_, $1)); }
5757
@@ -150,12 +150,12 @@ FOR(1, $1,[
150150
if (it == slots.end())
151151
return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows:
152152
153-
r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
153+
r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
154154
for (++it; it != slots.end(); ++it)
155155
{
156156
if (it->empty() || it->blocked())
157157
continue;
158-
r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
158+
r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
159159
}
160160
}
161161
@@ -201,12 +201,12 @@ FOR(1, $1,[
201201
if (it == reverse_iterator_type(slots.begin()))
202202
return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows:
203203
204-
r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
204+
r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
205205
for (++it; it != reverse_iterator_type(slots.begin()); ++it)
206206
{
207207
if (it->empty() || it->blocked())
208208
continue;
209-
r_ = (sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
209+
r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
210210
}
211211
}
212212
@@ -247,7 +247,7 @@ FOR(1, $1,[
247247
{
248248
if (slot.empty() || slot.blocked())
249249
continue;
250-
(sigc::internal::bitwise_equivalent_cast<call_type>(slot.rep_->call_))(LIST(slot.rep_, LOOP(_A_a%1, $1)));
250+
(sigc::internal::function_pointer_cast<call_type>(slot.rep_->call_))(LIST(slot.rep_, LOOP(_A_a%1, $1)));
251251
}
252252
}
253253
@@ -278,7 +278,7 @@ FOR(1, $1,[
278278
{
279279
if (it->empty() || it->blocked())
280280
continue;
281-
(sigc::internal::bitwise_equivalent_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
281+
(sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
282282
}
283283
}
284284
_DEPRECATE_IFDEF_END

0 commit comments

Comments
 (0)