reinterpret_cast to void* 不使用函数指针

2022-01-17 00:00:00 casting arm c++

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

I want to reinterpret cast a function pointer into a void* variable. The type of the function pointer will be of type Class* (*)(void*).

下面是示例代码,

class Test
{
    int a;
};

int main()
{
    Test* *p(void **a);
    void *f=reinterpret_cast<void*>(p);     
}

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

The above code works well with Visual Studio/x86 compilers. But with ARM compiler, it gives compilation error. Don't know why.

错误:#694:reinterpret_cast 不能抛弃 const 或其他类型限定词

Error: #694: reinterpret_cast cannot cast away const or other type qualifiers

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

我担心下面的解释.

函数指针和函数之间的转换常规指针(例如,强制转换 void(*)(void)void*).功能指针不一定相同大小作为常规指针,因为 on他们可能包含的一些架构额外的上下文信息.这在 x86 上可能可以正常工作,但是请记住,这是未定义的行为.

Casting between function pointers and regular pointers (e.g. casting a void (*)(void) to a void*). Function pointers aren't necessarily the same size as regular pointers, since on some architectures they might contain extra contextual information. This will probably work ok on x86, but remember that it's undefined behavior.

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

How to do such conversions from void (*)(void*) -> void* effectively so that atleast it compiles almost the same in most of the compilers ?

推荐答案

reinterpret_cast 不能用于将指向函数的指针转换为 void*.虽然 C 类型转换可以做的一些额外的事情是静态、重新解释和 const 类型转换的组合所不允许的,但这种转换不是其中之一.

reinterpret_cast can't be used to cast a pointer to function to a void*. While there are a few additional things that a C cast can do which aren't allowed by combination of static, reinterpret and const casts, that conversion is not one of them.

在 C 中允许强制转换,但未定义其行为(即,即使往返也不能保证有效).

In C the cast is allowed, but it's behavior isn't defined (i.e. even round trip isn't guaranteed to work).

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

Some POSIX functions need the conversion to be well useful.

我在这里玩过几个编译器:

I've played with several compilers I've here:

  • none 阻止 C 转换,即使在最高一致性模式下也是如此.有些根据警告和一致性级别发出警告,而其他人则无论我尝试什么都没有发出警告.
  • reinterpret_cast 对某些编译器来说是一个错误,即使是在更宽松的级别,而其他编译器在所有情况下都接受了它,但从未发出警告.

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

In the last available draft for C++0X, the reinterpret_cast between function pointers and objects pointers is conditionally supported.

请注意,这是否有意义将更多地取决于目标而不是编译器:像 gcc 这样的可移植编译器将具有目标体系结构和可能的 ABI 强加的行为.

Note that if that make sense or not will depend on the target more than the compiler: a portable compiler like gcc will have a behavior imposed by the target architecture and possibly ABI.

正如其他人所说,

Test* *p(void **a);

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

defines a function, not a pointer to function. But the function to pointer to function implicit conversion is made for the argument to reinterpret_cast, so what reinterpret_cast get is a Test** (*p)(void** a).

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

Thanks to Richard which makes me revisit the issue more in depth (for the record, I was mistaken in thinking that the pointer to function to pointer to object was one case where the C cast allowed something not authorized by C++ casts combinations).

相关文章