【问题标题】:Behaviour of const qualified function in CC 中 const 限定函数的行为
【发布时间】:2021-03-28 07:30:40
【问题描述】:

我想知道 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

产生以下警告:

警告:初始化使 '__attribute__((const))' 合格的函数指针来自不合格的 [-Wdiscarded-qualifiers]

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

警告:初始化从指针目标类型 [-Wdiscarded-qualifiers] 中丢弃“const”限定符

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


注意:cppreference 有以下段落:

如果使用 const 类型限定符(通过使用 typedef)声明函数类型,则行为未定义。

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

【问题讨论】:

    标签: c function constants typedef


    【解决方案1】:

    const 限定的函数指针和非 const 限定的函数指针有什么区别?

    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
    }
    

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

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

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

    vop *const cp_cfn = fn;
    

    【讨论】:

    • 感谢您的回答,但我实际上只是对const 放在星号之前的情况感到好奇。问题标题可能有点误导。我应该改变它吗?对于可能偶然发现这个问题并且实际上想要“常量指针”的人来说,这个答案将是一个很好的参考。
    【解决方案2】:

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

    来自C standard 的第 6.7.3p9 节:

    如果数组类型的规范包括任何类型限定符,则元素类型是如此限定的,而不是数组类型。 如果函数类型的规范包含任何类型限定符,则行为未定义。

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

    const vop cfn;
    

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

    const vop *cp_fn;
    

    两者都违反了 6.7.3p9。

    【讨论】:

      猜你喜欢
      • 2019-10-28
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 2010-09-14
      • 1970-01-01
      相关资源
      最近更新 更多