简体   繁体   English

将带有 const 参数的 function 分配给带有非 const 参数的 function 指针

[英]Assign function with const argument to function pointer with non const argument

Note: I have seen assigning-function-to-function-pointer-const-argument-correctness .注意:我看过assigning-function-to-function-pointer-const-argument-correctness While it applies to C++, the accepted answer seems to hint that this shouldn't be an issue.虽然它适用于 C++,但接受的答案似乎暗示这不应该成为问题。

I have compiled both with gcc and g++ and have the same issue.我已经用gccg++进行了编译并且遇到了同样的问题。 (g++ gives an error, and gcc a warning, but I assume this is due to different default flags). (g++ 给出错误,gcc 给出警告,但我认为这是由于不同的默认标志所致)。

A certain static analysis / linter tool we used at work (which shall remain anonymous) is causing this issue.我们在工作中使用的某个 static 分析/linter 工具(应保持匿名)导致此问题。 Since the functions don't modify the pointer int* num or the data itself, I should (must) declare the function args as const int* const num .由于函数不修改指针int* num或数据本身,我应该(必须)将 function args 声明为const int* const num

    typedef int (*funcptr)(int* num);
    
    int func1(      int* num)      { return *num +1; }
    int func2(const int* num)      { return *num +1; }
    int func3(      int* const num){ return *num +1; }
    int func4(const int* const num){ return *num +1; }
    
    int main(const int argc, const char** const argv){
        funcptr fptr;
        fptr = func1; //No warning - Signature exactly matches funcptr
        fptr = func2; //WARNING
        fptr = func3; //No warning
        fptr = func4; //WARNING
    }

gcc minimal.c

minimal.c:13:10: warning: assignment to ‘funcptr’ {aka ‘int (*)(int *)’} from incompatible pointer type ‘int (*)(const int *)’ [-Wincompatible-pointer-types]
   13 |     fptr = func2;
      |          ^
minimal.c:15:10: warning: assignment to ‘funcptr’ {aka ‘int (*)(int *)’} from incompatible pointer type ‘int (*)(const int * const)’ [-Wincompatible-pointer-types]
   15 |     fptr = func4;

g++ minimal.c

minimal.c: In function ‘int main(int, const char**)’:
minimal.c:13:12: error: invalid conversion from ‘int (*)(const int*)’ 
to ‘funcptr’ {aka ‘int (*)(int*)’} [-fpermissive]
   13 |     fptr = func2;
      |            ^~~~~
      |            |
      |            int (*)(const int*)
minimal.c:15:12: error: invalid conversion from ‘int (*)(const int*)’ 
to ‘funcptr’ {aka ‘int (*)(int*)’} [-fpermissive]
   15 |     fptr = func4;
      |            ^~~~~
      |            |
      |            int (*)(const int*)

EDIT: I understand why the standard applies to the above code, thanks to the accepted answer.编辑:由于接受了答案,我明白为什么该标准适用于上述代码。 But why would the following be acceptable?但为什么以下内容可以接受?

gcc minimal.c -Wall -Werror gcc minimal.c -Wall -Werror

int func(const int* const num){ return *num +1; }

int main(const int argc, const char** const argv){
    int aNumber = 4;
    int ret = func(&aNumber);
    return ret;
}

The function pointer funcptr is NOT in fact compatible with func2 . function 指针funcptr实际上与func2不兼容。

Two function types are compatible (ignoring cases including ... or old-style parameter declarations) if their return types are compatible, they have the same number of arguments, and the arguments types are compatible.两个 function 类型是兼容的(忽略包括...或旧式参数声明的情况)如果它们的返回类型兼容,它们具有相同数量的 arguments,并且 arguments 类型是兼容的。 The first two cases are obviously satisfied, so the interesting part is the third case.前两种情况显然是满意的,所以有趣的部分是第三种情况。

When type qualifiers are involved, two types are compatible if they are identically qualified versions of compatible types.当涉及类型限定符时,如果两种类型是兼容类型的相同限定版本,则它们是兼容的。 By this definition, a const int * and a int * are not compatible.根据这个定义,一个const int *和一个int *兼容的。 Therefore, funcptr and func2 are not compatible.因此, funcptrfunc2是不兼容的。

While a pointer to a non-qualified type may be converted to a pointer to a qualified version of the same type, by the above rules this does not apply to function parameters.虽然指向非限定类型的指针可以转换为指向相同类型的限定版本的指针,但根据上述规则,这不适用于 function 参数。

The rules for compatible qualified types are spelled out in section 6.7.3p10 of the C standard :兼容限定类型的规则在C 标准的第 6.7.3p10 节中有详细说明:

For two qualified types to be compatible, both shall have the identically qualified version of a compatible type;对于兼容的两个限定类型,两者都应具有兼容类型的相同限定版本; the order of type qualifiers within a list of specifiers or qualifiers does not affect the specified type.说明符或限定符列表中类型限定符的顺序不影响指定的类型。

And the rules for compatible function types are listed in section 6.7.6.3p15:兼容 function 类型的规则在第 6.7.6.3p15 节中列出:

For two function types to be compatible, both shall specify compatible return types .为了使两个 function 类型兼容,两者都应指定兼容的返回类型 Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator;此外,参数类型列表(如果两者都存在)应在参数数量和省略号终止符的使用上保持一致; corresponding parameters shall have compatible types.相应的参数应具有兼容的类型。 If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions.如果一种类型有参数类型列表,而另一种类型由 function 声明符指定,该声明符不是 function 定义的一部分,并且包含空标识符列表,则参数列表不应有省略号终止符,每个参数的类型应与应用默认参数提升产生的类型兼容。 If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier.如果一种类型有参数类型列表,另一种类型由包含(可能为空)标识符列表的 function 定义指定,则两者应在参数数量上一致,并且每个原型参数的类型应与类型兼容这是将默认参数提升应用于相应标识符类型的结果。 (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.) (在确定类型兼容性和复合类型时,以 function 或数组类型声明的每个参数都被视为具有调整后的类型,并且以限定类型声明的每个参数都被视为具有其声明类型的非限定版本。)

The parenthesized portion at the end is of particular note.最后带括号的部分特别值得注意。 It basically says that if a parameter is const it is omitted for the purpose of determining compatibility.它基本上是说,如果参数是const ,则出于确定兼容性的目的而将其省略。 This is why func3 doesn't trigger a warning, since a parameter of type int * const is equivalent in this context to int * .这就是func3不触发警告的原因,因为int * const类型的参数在此上下文中等同于int *

This does not apply to func2 because what the parameter points to is const , not the parameter itself.不适用于func2因为参数指向的const ,而不是参数本身。 So a parameter of type const int * is not adjusted to int * .所以const int *类型的参数不会调整为int *

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 作为 const 参数的函数指针 - Function pointer as a const argument 常量正确性-常量指针作为函数参数 - Const Correctness - Const Pointer As Function Argument const volatile指针函数参数 - const volatile pointer function argument 具有const参数的函数指针是否可以用作具有nonconst参数的函数指针? - Can a function pointer with a const argument be used as a function pointer with a nonconst argument? 是否正在转换一个函数指针,它接受一个常量指针参数到等效函数,但使用非常量指针参数可以吗? - Is casting a function pointer that takes a const pointer argument to the equivalent function but with non constant pointer arguments OK? C const指向const struct数组作为函数参数的指针 - C const pointer to const struct array as function argument 当给定`const char *`作为第一个参数时,C标准库函数`strchr`如何返回指向非const的指针? - How come C standard library function `strchr` returns pointer to non-const, when given `const char *` as first argument? 为什么在函数声明中传递const指针参数无效 - Why has passing a const pointer argument in function declaration no effect 函数的参数是指向声明为const的参数的指针,如何处理呢? - Function's parameter that is a pointer to an argument that was declared as const, how to handle it? 是否可以在激活 -Wall 时返回没有 const 限定符的 function 中的 const 指针参数的地址而不发出警告? - Is it possible to return an address of a const pointer argument in a function without const qualifier without a warning while -Wall is activated?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM