强制转换为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 cast。 有些人根据警告和一致性等级发出警告,其他人不管我尝试过什么都没有发出警告。
  • reinterpret_cast对于一些编译器来说是一个错误,即使在更宽松的层次上,其他编译器也会接受它,而不会发出警告。
  • 在最后的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_castreinterpret_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