gpt4 book ai didi

c - 使用 `const` 元素设计 C 容器?

转载 作者:太空狗 更新时间:2023-10-29 17:22:48 36 4
gpt4 key购买 nike

容器接口(interface)是否应该声明指向所包含的指针元素作为 const?

任务:用 C 语言设计一个容器(注意:这显然是关于纯 C 语言,不是关于 C++,也不是 C#)。容器将被提供指向项,并且应该返回指向项的指针。

有点无意义的 MWE,但这个想法扩展到有用的容器嗯:

#include <stdio.h>

typedef struct {
void *data;
} container_t;

void put(container_t *c, void *data)
{
c->data = data;
}

void *get(container_t *c)
{
return c->data;
}

int main(void)
{
container_t c;
int x = 42;
int *y;

put(&c, &x);
y = get(&c);

printf("value = %d\n", *y);

return 0;
}

到目前为止,还不错。

嗯,容器不应该使用指针来修改存储的数据。我想在界面中通过一个小的改变:

void put(container_t *c, const void *data)
^new

现在编译器让我做另一个改变,我真的做了同意:

typedef struct { const void *data; } container_t;
^new

然后编译器让我再做一个改变,这相当也符合逻辑:

const void *get(container_t *c)
^new

现在,编译器提示 y 不是 const int *,这让我有点不高兴。正确的处理方式是什么这个?

  • 不用const设计容器?我有时会看到这个库文档,例如 Glib[ https://developer.gnome.org/glib/2.42/glib-Double-ended-Queues.html#g-queue-push-tail] .但我真的很喜欢 const 提供的“安全”。

  • 记录 get 的返回值可能需要它是 const抛弃? IE。调用为

    y = (int *)get(&c);
  • 我宁愿不丢弃 const inside get功能,如

    return (void *)c->data;

    因为我不知道调用者是否真的应该考虑item const 完全没有。强调文字

最佳答案

您的接口(interface)正在制定契约(Contract),即传递给它的对象将永远不会通过该访问进行修改。所以本质上你需要两种容器类型,或者更一般的接口(interface),一种假设对象是可变的(void* 版本),另一种假设它可以被修改( >void const* 版本。

这是很多地方都会出现的问题,甚至在C库中也是如此。例如 memchr 就是这样一个接口(interface),它默默地对对象进行 const 转换。在现代 C 中,可以使用 _Generic 规避这种直接的叛逆行为。

您无法避免存储值然后在代码中完全不相关的地方重现它的问题。 C 和 POSIX 标准对于 tss_set/tss_getpthread_setspecific/pthread_getspecific 都有这个问题,并以不兼容的方式解决了这个问题。 C 变体对两者都有 void*,POSIX 变体有 void const* 用于设置,void* 用于获取。

关于c - 使用 `const` 元素设计 C 容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27570159/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com