Note: I have seen 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.
I have compiled both with gcc
and g++
and have the same issue. (g++ gives an error, and gcc a warning, but I assume this is due to different default flags).
A certain static analysis / linter tool we used at work (which shall remain anonymous) is causing this issue. 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
.
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
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;
}