问题
I know that declaring a function (or function pointer) with no parameter list (and without specifying void
in the parameter list) that means that the function (or function pointer) has an unknown number of arguments.
I wrote some test scripts to check this behavior out:
int my_func_1() {
return(0);
}
int my_func_2(int x) {
return(x);
}
int my_func_3(char x, ...) {
va_list va;
va_start(va, x);
return(va_arg(va, int));
}
int (*fp)();
fp = my_func_1;
printf("%d\n", fp());
fp = my_func_2;
printf("%d\n", fp(33));
fp = my_func_3;
printf("%d\n", fp(33, 44));
Which I've compiled on a 64 bit machine under linux as such:
gcc test.c -Wextra -pedantic -std=c1x -O3 -o test
The output is correct:
0
33
44
But I get this warning: assignment from incompatible pointer type
. How come this warning only shows up when using the vararg ellipsis?
Since the pointer type is considered incomplete assigning it a complete type should not constitute an "assignment from incompatible pointer type". Moreover, assigning complete types works without any warnings as long as the vararg ellipsis is not present
This other question asks nearly the same thing. The answers are all in the line of "it doesn't work that way" with no clear reference to the standard as to why it wouldn't work that way.
- Why does the compiler generate the warning?
- Is this behavior (warning aside) reliable?
- Is this behavior compiler specific (reading the other question it appears that mingw x86_64 didn't support it in 2011)?
- Is this behavior platform specific?
回答1:
See 6.7.5.3 of the C Standard:
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.
This says that the assignment of the varargs function to fp has incompatible types.
In addition, as I noted in my comments above, the program has undefined behavior which by definition is unreliable ... it may work in one version of one implementation on one platform but fail in other versions, implementations, and platforms ... it might even work one day but not the next, or in one part of a program but not another. Pragmatically, in some implementations the calling sequences of varargs and non-varargs functions are different, and your program is likely to crash when run on such an implementation.
来源:https://stackoverflow.com/questions/20671428/function-pointer-assignment-from-incompatible-pointer-type-only-when-using-var