23862

Function pointer “assignment from incompatible pointer type” only when using vararg ellipsis

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.

<hr>
    <li>Why does the compiler generate the warning?</li> <li>Is this behavior (warning aside) reliable?</li> <li>Is this behavior compiler specific (reading the other question it appears that mingw x86_64 didn't support it in 2011)?</li> <li>Is this behavior platform specific?</li> </ul>

    Answer1:

    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.

Recommend

  • Antlr lexer semantic predicate on an alternative
  • Install python3-venv module on linux mint
  • SQL Regex Pattern, How to match only a specific variable between two characters? (see Sample Output)
  • Add GET parameter in htaccess
  • Manually vectorized code 10x slower than auto optimized - what I did wrong?
  • LLVM-5.0 Makefile undefined reference fail
  • gevent fails to install in a python virtual environment on OS X Capitan
  • plot if col A has substring
  • initializing array of variable size inside a class
  • Viewing MJPEG Video Streams
  • How can I include multiple models in one view for in a Joomla 3.x component built with Component Cre
  • Mocking a imported function with pytest [duplicate]
  • Is C++ compilable with OpenMP and boost on MacOS?
  • How do I compile a C/C++ program through windows command prompt?
  • How to eliminate warning for passing multidimensional array as const multidimensional array?
  • Portable JRE on Linux - possible?
  • Best practice to eliminate magic numbers within a member function
  • Most efficient way to move table rows from one table to another
  • opencv display image without x server
  • configure: error: no acceptable C compiler found in $PATH
  • Custom preprocessing in caret
  • Implicit joins and Where in Doctrine - how?
  • Web.config system.webserver errors
  • Graphics.CopyFromScreen [Web application] + The handle is invalid
  • How solve “Qt: Untested Windows version 10.0 detected!”
  • C: Incompatible pointer type initializing
  • ADO and msqli connections very slow
  • Meteor: Do Something On Email Verification Confirmation
  • javaw.exe and eclipse startup problems
  • Modifying destination and filename of gulp-svg-sprite
  • Deserializing XML into class C#
  • 0x202A in filename: Why?
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Linker errors when using intrinsic function via function pointer
  • coudnt use logback because of log4j
  • File not found error Google Drive API
  • python draw pie shapes with colour filled
  • How to Embed XSL into XML