Reputation: 1674
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
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
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
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