【问题标题】:const-qualifier with typedef-ed function pointer带有 typedef 函数指针的 const 限定符
【发布时间】:2017-09-18 17:13:13
【问题描述】:

关于 typedef 函数指针在函数的参数中被 const 限定,C 标准有什么规定?例如,假设我有以下类型

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

我有一堆操作需要两个整数,执行操作,然后返回一个整数。然后我有一个执行实际函数指针调用的函数。

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 指针的函数。我只是想在某些情况下更强大的打字。

【问题讨论】:

  • 很高兴拥有但没有它你可能会改变什么?来电者不关心...
  • 请一次一个问题?
  • 那么,你的 C 书怎么说?什么不清楚?你的编译器是怎么说的?您使用typedef 的事实与您的问题有什么关系?尽管它的名字,它确实“定义”一个新类型!永远不要typedef 指针!

标签: c constants function-pointers typedef


【解决方案1】:

如果参数类型是操作,则调用者将指针的副本传递给函数,因此函数实际上无法更改该指针在调用者中指向的位置。在此处添加 const 关键字只是实现中的一种防御技术,可防止您重新分配本地副本。从这个意义上说,您甚至可能不需要 const 限定符来向您的库的客户端发出任何信号。

为了解决您的另一个问题,const 的两个位置具有相同的含义,因此您可以选择任何一个。

【讨论】:

    【解决方案2】:

    让外部世界 (.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); 的函数声明签名不足以保证“它实际上会调用给它的函数”。

    【讨论】:

      【解决方案3】:

      对于函数doOpOnce 的用户而言,是否使用const 限定符声明的函数指针并不重要,因为该函数处理用户提供的原始指针的副本作为参数。

      对于函数的用户这两个函数声明

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

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

      声明同一个函数。您可以在程序中包含这两个声明。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-04
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        • 2021-12-31
        相关资源
        最近更新 更多