5
votes

Is it possible to pass a function pointer as a const argument?

I get the following gcc error:

warning: type defaults to 'int' in declaration of 'f' [-Wimplicit-int] void execute(void (const *f)(void));

...when compiling this code:

#include <stdio.h>

void print(void);
void execute(void (const *f)(void));

int main(void)
{
    execute(print); // sends address of print
    return 0;
}

void print(void)
{
    printf("const!");
}

void execute(void (const *f)(void)) // receive address of print
{
    f();
}

This is not a duplicate of What is meaning of a pointer to a constant function?, which addresses pointers to const functions as opposed to a const function argument.

2

2 Answers

5
votes

The syntax you want is:

void execute(void (* const f)(void));

This says that f is a const pointer to a function that takes no arguments ((void) is a special syntax for no arguments) and returns nothing (void). A const on the right side of an * says that the pointer is const. A const on the left side says the pointer points to something that is const.

The fact that it is a const pointer means that you will not change f (assign a new value) in the function, and the compiler should give you an error if you do (unless the change is hidden from it, which it can be by casts). It does not say anything about the function itself—the function pointed to is not const in any sense because the parameter is const.

When you wrote:

void execute(void (const * f)(void));

the const on the left side of the * means that the pointer was pointing to something that was const, rather than that the pointer itself was const. Since it was saying the pointer was pointing to something there and you did not list a specific type, the compiler warned you that the type was missing (and defaulted to int).

0
votes

The const keyword should be placed between the pointer symbol (*) and the argument name (here, f):

void execute(void (* const f)(void))
{
  f();
}

Now if you try to change f's value:

void execute(void (* const f)(void))
{
  f = print;
  f();
}

...your compiler should output an error similar to this one, as expected:

Error: cannot assign to variable 'f' with const-qualified type