This can be compiled (despite being UB (right?) because fvp == nullptr
)
int f;
void* fvp{};
decltype(f)* fp = static_cast<decltype(f)*>(fvp);
but this cannot
void f() {}
void* fvp{};
decltype(f)* fp = static_cast<decltype(f)*>(fvp);
because (Clang says)
Static_cast from 'void *' to 'decltype(f) *' (aka 'void (*)()') is not allowed [bad_cxx_cast_generic]
Why is this the case? And where from the standard do I understand this? I guess [expr.static.cast] is where I should look at; specifically 7, but I'm not sure.
Follow up question on the reason why I wanted to ask this one.
This is not allowed because [expr.static_cast] does not allow it. Indeed, the relevant language is:
No other conversion shall be performed explicitly using a
static_cast
.
Since there is no conversion listed that would permit conversion from void*
to a function pointer type, that conversion is not allowed.
The rationale is that function and data pointers may have different sizes or alignment requirements.
You might consider a reinterpret_cast
, which conditionally supports such conversions. But it would be better to use a design that does not require such conversions. If you need to type-erase a function pointer, you will still need reinterpret_cast
but can use e.g. void(*)()
as the erased type, which is always supported.