简体   繁体   English

为什么我不能将 void* static_cast 转换为函数指针?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM