【问题标题】:const *const pointers in function parameters函数参数中的 const *const 指针
【发布时间】:2023-03-20 03:40:01
【问题描述】:

我有一个关于函数参数中涉及指针的最佳实践以及是否应将它们指定为*constconst *const 的问题。我知道对于const 的使用或过度使用有不同的看法,但至少有一些使用是捕捉意外错误的好方法。

假设你有以下函数,它是基于链表的队列实现的一部分:

void enqueue(struct queue *q, void *data)
{
    struct queue_node *item = malloc(sizeof(*item));
    item->data = data;

    [add node to linked list, specifics are not relevant here]
}

struct queue_node 定义为

struct queue_node {
        struct queue_node *next;
        void *data;
};

data 不打算在此函数中进行修改,因此将data 设置为void *const 类型似乎是个好主意,这样您就不会意外地执行data = item->data 之类的操作而不是@987654331 @。

下一个级别是将data 定义为const void *const,这意味着您也无法更改data 指向的内容。但是,这会导致有关从指针中丢弃 const 限定符的警告。如果我理解正确,进一步使用这样的指针被认为是未定义的行为。使用演员表 (item->data = (void *)data) 似乎很笨重。

这里最好的方法是什么? const void *const 是否过度保护?感觉void *const 足以捕获大多数错误。

【问题讨论】:

  • 如果item->data 的类型为void *,我认为data 参数为void *void * const 是有意义的,即使该函数不会修改指向的对象data。如果item->data 的类型为const void *,我只会使用const void * dataconst void * const data

标签: c pointers casting


【解决方案1】:

由于函数参数的更改不会反映在调用函数中,因此没有理由确保参数本身是只读的。但是, 很有用,可以确保指针参数指向的内容不会改变。因此,如果您不想更改 data 指向的内容,您可以将函数签名更改为:

void enqueue(struct queue *q, const void *data)

请注意,这仅在struct queue_nodedata 成员具有const void * 类型时才有效。如果不是,那么您不想在data 参数上使用const

【讨论】:

  • (原始帖子已编辑以包含结构定义)datavoid * 类型,因此以后的检索可以不进行强制转换,并且可以修改指向的对象。
  • @sj95126 这意味着函数不保证data不会被修改,因此参数应该const
  • 好的,谢谢。听起来解决方案就是坚持使用void *。这不能防止像data = item->data 而不是item->data = data 这样的东西,但是当队列中有一个项目丢失或损坏data 时,其效果应该很明显。
猜你喜欢
  • 1970-01-01
  • 2018-09-02
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多