reinterpret_cast to void*不使用函数指针

vpr*_*jan 6 c++ arm casting

我想重新解释将函数指针强制转换为void*变量.函数指针的类型将是类型Class* (*)(void*).

以下是示例代码,

class Test
{
    int a;
};

int main()
{
    Test* *p(void **a);
    void *f=reinterpret_cast<void*>(p);     
}
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于Visual Studio/x86编译器.但是使用ARM编译器,它会产生编译错误.不知道为什么.

错误:#694:reinterpret_cast无法抛弃const或其他类型的限定符

我在将函数指针转换为另一种类型时阅读了解释

我担心下面的解释.

在函数指针和常规指针之间进行转换(例如,将a转换void (*)(void)为a void*).函数指针的大小不一定与常规指针相同,因为在某些体系结构中它们可能包含额外的上下文信息.这可能在x86上运行正常,但请记住它是未定义的行为.

如何void (*)(void*) -> void*有效地进行这样的转换,以至于它在大多数编译器中编译几乎相同?

APr*_*mer 7

reinterpret_cast不能用于将函数的指针强制转换为a void*.虽然C cast可以执行一些额外的操作,静态,重新解释和const转换组合不允许这种转换,但转换不是其中之一.

在C中,允许使用强制转换,但是它的行为没有定义(即使往返行程也不能保证工作).

一些POSIX函数需要转换才能很有用.

我和我在这里玩了几个编译器:

  • 即使在最高一致性模式下,也无法阻止C强制转换.有些人根据警告和一致性等级给出警告,其他人在我尝试的时候没有发出任何警告.
  • 一些编译器的reinterpret_cast是一个错误,即使是在更宽松的层面,而其他编译器在所有情况下都接受它而没有发出警告.

在C++ 0X的最后一个可用草案中,reinterpret_cast有条件地支持函数指针和对象指针.

请注意,如果有意义与否将取决于目标超过编译:便携式编译器GCC一样会通过目标体系结构,并可能ABI强加的行为.

正如其他人所说的那样,

Test* *p(void **a);
Run Code Online (Sandbox Code Playgroud)

定义一个函数,而不是一个指向函数的指针.但是指向函数隐式转换的函数是针对reinterpret_cast的参数进行的,所以reinterpret_cast得到的是a Test** (*p)(void** a).

感谢理查德让我更深入地重新审视这个问题(对于记录,我错误地认为指向对象的函数的指针是C cast允许未经C++强制转换组合授权的情况).


Tob*_*ias 7

reinterpret_cast只能用于

  • 添加常量
  • 将指针转换为足以容纳和返回的整数类型
  • 将指向函数的指针转换为指向不同类型函数的指针
  • 将指向对象的指针转换为指向不同类型对象的指针
  • 将指向成员函数的指针转换为指向不同类型的成员函数的指针
  • 将指向成员对象的指针转换为指向不同类型的成员对象的指针
  • 并且只要使用上述规则进行第二次演员,reinterpret_cast<T&>(x)就相当于*reinterpret_cast<T*>(&x)(使用内置&*).

(见标准第5.2.10节)

这尤其意味着从指向函数的指针的转换void *是不可能的,但您可以将它强制转换为void(*)().


编辑(2017):上面的答案只适用于C++ 03.在C++ 11到C++ 17中,如果void *允许在函数指针之间进行转换,则它是实现定义的.这通常是POSIX兼容系统的情况,因为dlsym()声明返回void *,并且客户端期望reinterpret_cast它到正确的函数指针类型.

有关允许的完整转化列表,请访问cppreference.com.