带有typedef-ed函数指针的const-qualifier

时间:2017-09-18 17:13:14

标签: c const function-pointers typedef

关于在函数参数中使用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指针。我只是想在某些情况下加强打字。

3 个答案:

答案 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);

声明相同的一个功能。您可以在程序中包含这两个声明。

只有在函数定义中,您才能将此指针(函数的局部变量)更改为其任何参数。

相关问题