关于在函数参数中使用const限定的typedef-ed函数指针,C标准有什么说法?例如,假设我有以下类型
typedef int (*Operation)(int a, int b);
我有一堆操作需要两个整数,执行操作,然后返回一个int。然后我有一个执行实际函数指针调用的函数。
int doOpOnce(const Operation op, int a, int b)
{
return op(a, b);
}
我想保证函数指针在doOpOnce
调用期间不会发生变化,我还想向doOpOnce
的用户说明它实际上会调用给它的函数。这有效吗?之间有什么区别:
int doOpOnce(const Operation op, int a, int b)
int doOpOnce(Operation const op, int a, int b)
最后,这是一个例子。它使用带有标志-std=c99 -Wall -Wextra -pedantic
的gcc 4.9.2编译,当我尝试更改我的const函数指针时它正确错误。
#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;
}
我不想将const限定符添加到Operation
typedef,因为我有其他函数可以修改Operation
指针。我只是想在某些情况下加强打字。
答案 0 :(得分:1)
让外界(.h)看到int doOpOnce(Operation op, int a, int b);
和你的.c文件实现int doOpOnce(Operation const op, int a, int b) {
,以“保证函数指针在doOpOnce期间不会改变”
“我还想向doOpOnce的用户说明它实际上会调用给它的函数。”属于代码文档。
int doOpOnce(Operation const op, int a, int b);
的函数声明签名不足以保证“它实际上会调用给它的函数”。
答案 1 :(得分:1)
如果参数类型为Operation,则调用者将指针的副本传递给函数,因此该函数实际上无法更改指针指向调用者的位置。在这里添加const关键字只是实现中的一种防御性技术,可以防止您重新分配本地副本。从这个意义上讲,您甚至可能不需要const限定符来向您的库的客户端发送任何信号。
为了解决您的其他问题,const的两个展示位置具有相同的含义,因此您可以选择您想要的任何一个。
答案 2 :(得分:0)
对于函数doOpOnce
的用户,使用const
限定符声明函数的指针是不重要的,因为该函数处理用户提供的原始指针的副本参数。
对于函数的用户,这两个函数声明
int doOpOnce(const Operation op, int a, int b);
和
int doOpOnce( Operation op, int a, int b);
声明相同的一个功能。您可以在程序中包含这两个声明。
只有在函数定义中,您才能将此指针(函数的局部变量)更改为其任何参数。