This is a tangential follow up to my previous question The address of a function matching a bool vs const void* overload. The answerer explained:
The
(All quotes are from N3337 and are equivalent for every single draft until N4296 from there on, i.e. this answer is valid at least for C++11 and C++14 but not for C++03 as the first quote of this answer does not exist in there.)
[expr.reinterpret.cast]/8:
Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the orignal pointer value.
This is contained in your listing. You argue that void
is not an object type, but you didn't consider the crucial [basic.compound]/3:
The type of a pointer to
void
or a pointer to an object type is called an object pointer type.
(That is, a object pointer type is not necessarily a "pointer to object type" - standard terminology got you there.)
The only reason that
f = reinterpret_cast<decltype(f)>(s);
Isn't fine on GCC or Clang is that the target type, as opposed to the source expression, is not decayed - and you can clearly not cast void*
to a function type. You need to make the target type a pointer to function, then it works.