强制转换为void *不能与函数指针一起工作
我想重新解释一个函数指针到一个void *变量中。 函数指针的类型将是Class* (*)(void*)
。
以下是示例代码,
class Test
{
int a;
};
int main()
{
Test* *p(void **a);
void *f=reinterpret_cast<void*>(p);
}
上述代码适用于Visual Studio / x86编译器。 但是,使用ARM编译器时,会产生编译错误。 不知道为什么。
错误:#694:reinterpret_cast不能丢弃const或其他类型限定符
我读了将一个函数指针转换为另一种类型的解释
我很关心下面的解释。
在函数指针和常规指针之间进行投射(例如,将void (*)(void)
投射到void*
)。 函数指针不一定与常规指针的大小相同,因为在某些体系结构中它们可能包含额外的上下文信息。 这可能会在x86上正常工作,但请记住它是未定义的行为。
如何从void (*)(void*) -> void*
有效地进行这样的转换,以便至少它在大多数编译器中编译几乎相同?
reinterpret_cast
不能用于将指针转换为void*
。 尽管C cast可以做一些其他的事情,静态,重新解释和常量强制转换不允许,但这种转换不是其中之一。
在C中,演员是允许的,但它的行为没有定义(即,即使往返也不能保证工作)。
一些POSIX函数需要转换才能很好用。
我已经与我在这里的几个编译器玩过了:
在最后的C ++ 0X草案中,函数指针和对象指针之间的reinterpret_cast
是有条件支持的。
请注意,如果这样做有意义还是不会依赖于目标而不是编译器:像gcc这样的可移植编译器将会具有由目标体系结构和可能的ABI强加的行为。
正如其他人所说的那样,
Test* *p(void **a);
定义一个函数,而不是指向函数的指针。 但是指向函数隐式转换的函数是针对reinterpret_cast的参数进行的,所以reinterpret_cast get是一个Test** (*p)(void** a)
。
感谢Richard,这让我更深入地回顾了这个问题(对于记录,我错误地认为指向函数的指针指向的对象是C转换允许未经C ++授权的东西转换组合的一种情况)。
reinterpret_cast只能用于
reinterpret_cast<T&>(x)
等同于*reinterpret_cast<T*>(&x)
(使用内建的&
和*
),只要使用上述规则可以进行第二次转换。 (见标准的第5.2.10节)
这尤其意味着从指向函数的指针到void *
是不可能的,但是您可以将其void(*)()
为void(*)()
。
编辑(2017):上面的答案只适用于C ++ 03。 在C ++ 11到C ++ 17中,如果函数指针和void *
之间的转换被允许,它就是实现定义的。 在POSIX兼容系统上,这通常是这种情况,因为dlsym()
被声明为返回void *
,并且客户端需要reinterpret_cast
它reinterpret_cast
为正确的函数指针类型。
请参阅cppreference.com以获取允许的完整转换列表。
如果您只是想在列表中存储不同类型的函数指针,则可以将其转换为常用的函数指针类型:
class Test {
int a;
};
int main()
{
Test* *p(void **a);
void (*f)()=reinterpret_cast<void (*)()>(p);
}
这可以通过reinterpret_cast
(5.2.10 / 6)来完成:
指向函数的指针可以显式转换为指向不同类型函数的指针。 通过指向与函数定义中使用的类型不同的函数类型(8.3.5)的指针调用函数的效果未定义。 除了将“指针指向T1”类型的右值转换为类型“指向T2的指针”(其中T1和T2是函数类型)并且回到其原始类型产生原始指针值之外,不指定此类指针转换的结果。
链接地址: http://www.djcxy.com/p/73757.html上一篇: cast to void* not working with function pointers
下一篇: Should I use static