简体   繁体   English

如何将void(*)()类型的指针转​​换为void *

[英]How to convert a pointer of type void(*)() to void*

How to convert a pointer of type void(*)() to void * ? 如何将void(*)()类型的指针转​​换为void *

is any of the following operators can be used to do so? 是否可以使用以下任何一个运算符?

  • const_cast
  • static_cast
  • dynamic_cast
  • reinterpret_cast

Example: all of the following are compiled ( tried in Visual Studio 2017 ), I wonder if they all have the same result after converting. 示例:编译以下所有内容( 在Visual Studio 2017中尝试过 ),我想知道它们在转换后是否都具有相同的结果。

void operation(void(*callback)()) {

    void* test1 = callback;
    void* test2 = static_cast<void*>(callback);
    void* test3 = reinterpret_cast<void*>(callback);
}

In ISO standard C++, there is no implicit conversion from any function pointer type to any object pointer type. 在ISO标准C ++中,没有从任何函数指针类型到任何对象指针类型的隐式转换。 So this line is ill-formed. 所以这条线是不正确的。

void* test1 = callback;

For the compiler to accept this without a diagnostic is a bug 1 (you do have warnings enabled, correct?) 对于编译器在没有诊断的情况下接受这个是错误1 (你确实启用了警告,对吗?)

static_cast between any object pointer type and a function pointer type (either direction) is prohibited in standard C++. 标准C ++中禁止在任何对象指针类型和函数指针类型(任一方向)之间使用static_cast The controlling rule is found in 5.2.9: 控制规则见5.2.9:

Otherwise, the static_cast shall perform one of the conversions listed below. 否则, static_cast将执行下面列出的转换之一。 No other conversion shall be performed explicitly using a static_cast . 不能使用static_cast明确执行其他转换。

Since none of the rules above or below discuss function pointer casts, this forbids the line 由于上面或下面的规则都没有讨论函数指针强制转换,因此禁止该行

void* test2 = static_cast<void*>(callback);

However, this is not necessarily a separate compiler bug, because one of the rules does permit static_cast to be used to accomplish any implicit conversion. 但是,这不一定是单独的编译器错误,因为其中一个规则允许使用static_cast来完成任何隐式转换。

The final line is the only correct one: 最后一行是唯一正确的:

void* test3 = reinterpret_cast<void*>(callback);

The controlling rule is provided in the specification for reinterpret_cast (5.2.10) reinterpret_cast规范中提供了控制规则(5.2.10)

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 original pointer value. 这种转换的含义是实现定义的,除非实现支持两个方向的转换,将一种类型的prvalue转换为另一种类型并返回,可能具有不同的cv-qualification,将产生原始指针值。


1 When standard-compliant mode is enabled using /Za , the Microsoft C++ compilers do correctly reject the copy-initialization and static_cast attempts: 1使用/Za启用标准兼容模式时,Microsoft C ++编译器会正确拒绝复制初始化和static_cast尝试:

source_file.cpp(8): error C2440: 'initializing': cannot convert from void (*)(void) to void * source_file.cpp(8):错误C2440:'initializing':无法从void (*)(void)void *

source_file.cpp(8): note: Types pointed to are unrelated; source_file.cpp(8):注意:指向的类型是不相关的; conversion requires reinterpret_cast, C-style cast or function-style cast 转换需要reinterpret_cast,C风格的转换或函数式转换

source_file.cpp(9): error C2440: static_cast : cannot convert from void (*)(void) to void * source_file.cpp(9):错误C2440: static_cast :无法从void (*)(void)void *

source_file.cpp(9): note: Types pointed to are unrelated; source_file.cpp(9):注意:指向的类型是不相关的; conversion requires reinterpret_cast, C-style cast or function-style cast 转换需要reinterpret_cast,C风格的转换或函数式转换

In Standard C++, since C++11, it is conditionally-supported , which means that an implementation may or may not support it, and must document whether it is supported. 在标准C ++中,从C ++ 11开始,它是有条件支持的 ,这意味着实现可能支持也可能不支持,并且必须记录它是否受支持。

For implementations that do support this cast, the appropriate cast operator to use is reinterpret_cast . 对于支持此强制转换的实现,要使用的适当强制转换运算符是reinterpret_cast The details can be found in the C++14 standard [expr.reinterpret.cast]/8. 详细信息可以在C ++ 14标准[expr.reinterpret.cast] / 8中找到。

It's an error to try and convert a function pointer to an object pointer with no cast ([conv.ptr]), or with static_cast ([expr.static.cast]/5). 尝试将函数指针转换为没有强制转换([conv.ptr])或static_cast ([expr.static.cast] / 5)的对象指针是错误的。 If your compiler permits this in standard mode and doesn't issue a diagnostic then the compiler is non-conforming. 如果您的编译器在标准模式下允许此操作并且未发出诊断,则编译器不符合要求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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