Search code examples
cfunction-pointersconst-correctness

What is meaning of a pointer to a constant function?


Pointers can be declared as pointing to mutable (non-const) data or pointer to constant data.
Pointers can be defined to point to a function.

My coworkers and I were discussing the use of "const" with pointers and the question came up regarding the use of const with function pointers.

Here are some questions:

  1. What is the meaning of a pointer to a constant function versus a pointer to a non-constant function?
  2. Can a function be const?
  3. Can a function be non-const (mutable)?
  4. What is the proper (safe) syntax for passing a function pointer?

Edit 1: Function pointer syntax

typedef void (*Function_Pointer)(void); // Pointer to void function returning void.

void function_a(Function_Pointer p_func); // Example 1.
void function_b(const Function_Pointer p_func); // Example 2.
void function_c(Function_Pointer const p_func); // Example 3.
void function_d(const Function_Pointer const p_func); // Example 4.

The above declarations are examples of treating a function pointer like a pointer to an intrinsic type.

A data, variable or memory pointer allows for the above combinations.
So the questions are: can a function pointer have the same combinations and what is meant by a pointer to a const function (such as Example 2)?


Solution

  • In C, there's no such thing as a function being const or otherwise, so a pointer to a const function is meaningless (shouldn't compile, though I haven't checked with any particular compiler).

    Note that although it's different, you can have a const pointer to a function, a pointer to function returning const, etc. Essentially everything but the function itself can be const. Consider a few examples:

    // normal pointer to function
    int (*func)(int);
    
    // pointer to const function -- not allowed
    int (const *func)(int);
    
    // const pointer to function. Allowed, must be initialized.          
    int (*const func)(int) = some_func;
    
    // Bonus: pointer to function returning pointer to const
    void const *(*func)(int);
    
    // triple bonus: const pointer to function returning pointer to const.
    void const *(*const func)(int) = func.
    

    As far as passing a pointer to a function as a parameter goes, it's pretty simple. You normally want to just pass a pointer to the correct type. However, a pointer to any type of function can be converted to a pointer to some other type of function, then back to its original type, and retain the original value.