首页 文章

如何在函数指针上抛弃const?

提问于
浏览
3

以下代码在GCC上编译清理但在Clang上收到错误:

typedef void (MyFuncPtr)();
void foo(const MyFuncPtr* ptr)
{   
    MyFuncPtr* myTestPtr = ptr;
}

Clang错误:

error: cannot initialize a variable of type 'MyFuncPtr *' (aka 'void (*)()') with an lvalue of type 'const MyFuncPtr *'
  (aka 'void (const *)()')

我尝试了以下解决方案,除了C风格的演员之外他们都会遇到错误:

const_cast会:

MyFuncPtr* myTestPtr = const_cast<MyFuncPtr*>(ptr);

错误:

error: const_cast to 'MyFuncPtr *' (aka 'void (*)()'), which is not a reference, pointer-to-object, or pointer-to-data-member

reintepret_cast:

MyFuncPtr* myTestPtr = reinterpret_cast<MyFuncPtr*>(ptr);

错误:

error: reinterpret_cast from 'const MyFuncPtr *' (aka 'void (const *)()') to 'MyFuncPtr *' (aka 'void (*)()') casts away
  qualifiers

C风格演员:

MyFuncPtr* myTestPtr = (MyFuncPtr*) ptr;

成功!

问题:
为什么const_cast不能处理函数指针?
使用C风格的演员阵容是唯一的解决方案吗?
为什么这对GCC没有投射有效?

提前致谢!

编译器版本:

  • G版本4.6.3
  • clang版本3.5.0.210790

1 回答

  • 3

    在您的代码中, MyFuncPtr 是函数类型(不是函数指针类型) . 您的代码尝试使用 const MyFuncPtr 类型,它将 const 应用于函数类型 .

    但是,根据C 14 [dcl.fct] / 6中的注释,没有const限定的函数类型:

    cv-qualifier-seq在函数声明符中的作用与在函数类型之上添加cv-qualification不同 . 在后一种情况下,忽略cv限定符 . [注意:具有cv-qualifier-seq的函数类型不是cv限定类型;没有cv限定的函数类型 . - 尾注]

    本节主要讨论cv-qualifier-seq,它是在成员函数之后发生的限定符 . 但是,顺便说一句,它似乎指定一般应用于函数类型的cv限定符将被忽略 .

    因此,您的代码应该与以下内容相同:

    typedef void (MyFuncPtr)();
    void foo(MyFuncPtr* ptr)
    {   
        MyFuncPtr* myTestPtr = ptr;
    }
    

    这意味着clang会报告错误 .

相关问题