[英]Why can't I static_cast a void* to a pointer-to-function?
This can be compiled (despite being UB (right?) because fvp == nullptr
)这可以被编译(尽管是 UB(对吧?)因为
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)因为(Clang 说)
Static_cast from 'void *' to 'decltype(f) ' (aka 'void ( )()') is not allowed [bad_cxx_cast_generic]
不允许从“void *”到“decltype(f) ”(又名“void ( )()”)的 Static_cast [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;
我想[expr.static.cast]是我应该看的地方; specifically 7 , but I'm not sure.
特别是7 ,但我不确定。
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.这是不允许的,因为 [expr.static_cast] 不允许。 Indeed, the relevant language is:
事实上,相关的语言是:
No other conversion shall be performed explicitly using a
static_cast
.不得使用
static_cast
显式执行其他转换。
Since there is no conversion listed that would permit conversion from void*
to a function pointer type, that conversion is not allowed.由于没有列出允许从
void*
转换为 function 指针类型的转换,因此不允许进行该转换。
The rationale is that function and data pointers may have different sizes or alignment requirements .理由是 function 和数据指针可能有不同的大小或 alignment 要求。
You might consider a reinterpret_cast
, which conditionally supports such conversions.您可能会考虑
reinterpret_cast
,它有条件地支持此类转换。 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 eg void(*)()
as the erased type, which is always supported .如果您需要类型擦除 function 指针,您仍然需要
reinterpret_cast
但可以使用例如void(*)()
作为擦除类型,它始终受到支持。
where from the standard do I understand this?
我从标准的哪里可以理解这一点? I guess [expr.static.cast] is where I should look at;
我想 [expr.static.cast] 是我应该看的地方; specifically 7, but I'm not sure
具体是 7,但我不确定
Basically, there is no guarantee for a full-round trip between void*
and a function pointer.基本上,不能保证
void*
和 function 指针之间的完整往返。
This can be seen from expr.reinterpret.cast#8 which says:这可以从expr.reinterpret.cast#8中看出:
Converting a function pointer to an object pointer type or vice versa is conditionally-supported.
有条件地支持将 function 指针转换为 object 指针类型,反之亦然。 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 original pointer value.
这种转换的含义是实现定义的,除非实现支持双向转换,将一种类型的纯右值转换为另一种类型并返回,可能具有不同的 cv 限定,应产生原始指针值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.