thndrwrks
thndrwrks

Reputation: 1674

const-qualifier with typedef-ed function pointer

What does the C standard have to say regarding typedef-ed function pointers being const qualified in parameters to functions? For example, say I have the following type

typedef int (*Operation)(int a, int b);

I've got a bunch of operations which take two ints, performs the operation, and then returns an int. Then I have a function which performs the actual function pointer call.

int doOpOnce(const Operation op, int a, int b)
{
    return op(a, b);
}

I want to guarantee that the function pointer doesn't change during the doOpOnce call and I also want to document to users of doOpOnce that it will actually call the function given to it. Is this valid? Is there any difference between:

int doOpOnce(const Operation op, int a, int b)
int doOpOnce(Operation const op, int a, int b)

Finally, here is an example. Its compiled with gcc 4.9.2 with flags -std=c99 -Wall -Wextra -pedantic and it correctly errors when I try to change my const function pointer.

#include <stdio.h>

typedef int (*Operation)(int a, int b);

int opAdd(int a, int b)
{
    return a + b;
}

int opSub(int a, int b)
{
    return a - b;
}

int doOpOnce(const Operation op, int a, int b)
{
    op = opSub; // error: assignment of read-only parameter 'op'

    return op(a, b);
}

int main()
{
    printf("%d\n", doOpOnce(opAdd, 10, 20));

    return 0;
}

I do not want to add the const qualifier to the Operation typedef as I have other functions which CAN modify Operation pointers. I just want stronger typing in some circumstances.

Upvotes: 1

Views: 1123

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

For the user of the function doOpOnce it is unimportant whether the pointer to function declared with the const qualifier or not because the function deals with a copy of the original pointer supplied by the user as an argument.

For the user of the function these two function declarations

int doOpOnce(const Operation op, int a, int b);

and

int doOpOnce( Operation op, int a, int b);

declare the same one function. You may include the both declarations in the program.

It is only within the function definition you will not be able to change this pointer that is a local variable of the function as any its parameter. .

Upvotes: 0

templatetypedef
templatetypedef

Reputation: 372972

If the parameter type is Operation, the caller passes a copy of the pointer into the function and so the function can't actually change where that pointer is pointing back in the caller. Adding the const keyword here would just be a defensive technique in the implementation that prevents you from reassigning your local copy. In that sense, you probably don't even need the const qualifier to signal anything to the client of your library.

To address your other question, the two placements of const have the same meaning, so you can pick whichever one you'd like.

Upvotes: 1

chux
chux

Reputation: 154280

Let the outside world (.h) see int doOpOnce(Operation op, int a, int b); and your .c file implement int doOpOnce(Operation const op, int a, int b) { so "to guarantee that the function pointer doesn't change during the doOpOnce"


"I also want to document to users of doOpOnce that it will actually call the function given to it. " belongs in the code documentation.

A function declaration signature of int doOpOnce(Operation const op, int a, int b); is not sufficient to guarantee "it will actually call the function given to it".

Upvotes: 1

Related Questions