C 中 const 限定函数的行为

Behaviour of const qualified function in C

我想知道 const 限定函数指针是否有任何区别,因为我能想到的唯一含义是自动 const 限定其参数,当然不是这种情况。

我创建了一个小示例文件 (test.c):

typedef void* vop(void*);

vop  fn;
const vop cfn;

int main(void){
    vop *p_fn = fn;
    const vop *cp_fn = fn;  // <- gives compiler warning
    vop *p_cfn = cfn;
    const vop *cp_cfn = cfn;
}

和运行

gcc -Wall -Wno-unused-variable -c test.c

这会产生以下警告:

warning: initialization makes '__attribute__((const))' qualified function pointer from unqualified [-Wdiscarded-qualifiers]

因此,将“指向 const vop 的指针”分配给类型为“指向 vop 的指针”的变量是“可以”的,如果它不是函数指针,则会产生如下内容:

warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]

但现在它警告相反的情况。那么问题来了:const限定的函数指针和非const限定的函数指针有什么区别?


注:cppreference有如下段落:

If a function type is declared with the const type qualifier (through the use of typedef), the behavior is undefined.

我看到的警告是“未定义行为”的结果,还是本段不适用于这种情况(如果不适用,在什么情况下可以适用)?

What is the difference between const qualified function pointers and those that are not const qualified?

const 具有通常的含义 - 一个可以修改,const 一个不能。示例:

void something();
void something_else();
int main() {
    void (*normal_pointer)() = something;
    normal_pointer = something_else; // all fine

    void (*const const_qualified_pointer)() = something;
    const_qualified_pointer = something_else; // error

    // for fun, let's aad typedef examples
    // similar with a typedef, if you want to
    typedef void functype();
    functype *pnt = something;
    pnt = something_else; // all fine

    functype *const cpnt = something;
    cpnt = something_else; // error

    // note that if typedef is already a pointer... then it's already a pointer
    typedef void (*functypepnt)();
    functypepnt pnt2 = something;
    pnt2 = something_else; // all fine

    const functypepnt cpnt2 = something;
    cpnt2 = something_else; // error
}

Is the warning i saw a result of that "undefined behaviour" or does this paragraph not apply in this case (and if not, in what case can it be applied)?

是的。 vop 是函数类型。 const vop 是未定义的行为。 gcc 发出警告并忽略限定符。

您可能想要 const-限定指针本身,而不是指向的类型:

vop *const cp_cfn = fn;

函数类型不能有任何类型限定符,包括 const。这样做吧undefined behavior.

来自 C standard 的第 6.7.3p9 节:

If the specification of an array type includes any type qualifiers, the element type is so-qualified, not the array type. If the specification of a function type includes any type qualifiers, the behavior is undefined.

这声明了一个 const 函数类型:

const vop cfn;

这声明了一个指向 const 函数类型的指针:

const vop *cp_fn;

两者都违反了 6.7.3p9.