C 中的泛型编程 - void*- const 正确性

Posted

技术标签:

【中文标题】C 中的泛型编程 - void*- const 正确性【英文标题】:generic programming in C - void*- const-correctness 【发布时间】:2016-01-29 16:39:30 【问题描述】:

我的问题是,如果两者都定义是正确的:

typedef void* Elem;
typedef const void* const constElem; 

如果我知道我会使用 const 和非 const 通用元素,例如将 copyElem 函数作为参数,我更愿意将它作为 const 获取,因为 const 正确性,这是否实用?

【问题讨论】:

对其中任何一个使用 typedef 都是(IMO)不切实际的。 我认为你只想要constElem 定义中的第一个const。第二个const 指定constElem 类型的变量是常量,因此不能更改。我想你的意思是只有 constElem points 不能改变。 pcarter,实际上是的,但是第一个 const 无论如何都不会打扰,不是吗?例如,对于 Elem 的复制函数,没有理由改变指针指向,因为它指向的内容。 通常你会想要避免使用 typedef 的指针。它们通常只会掩盖指针间接的级别并使代码的可读性降低(更不用说更难调试了)。 【参考方案1】:

我看不出这里有什么正确性问题,除非是的,你提供的两个 typedef 在语法上都是正确的,并且程序可能对这两种类型都有用。

然而,就风格而言,将指针性质隐藏在 typedef 后面是一种糟糕的形式。它很容易变得混乱。

将任何内容定义为void * 也有点问题——它没有提供任何意义的类型安全,也没有太多的语义帮助。如果你真的想接受指向任何东西的指针,那么就说void *。另一方面,如果您想隐藏结构类型的详细信息,则只需将该结构类型声明为不完整类型,然后保持原样:

struct Elem;

为方便起见,可选地,typedef:

typedef struct Elem Elem;

就个人而言,再次从风格上讲,我更愿意看到 const 关键字,而不是看到在 const 中滚动的 typedef,无论指定多么明确。

还要注意,除了所有的风格问题,这个特殊的 typedef ...

typedef const void* const constElem;

... 似乎用处很窄。它指定一个指针,其值不能更改,并且指向一个也不能更改的对象。指向const 对象的非const 指针通常是您想要的。还要注意,constElem 应该表示什么的不确定性是在 Elem 类型定义中滚动指针性质的结果之一。

【讨论】:

【参考方案2】:

const void *const 不会给你买多少,除非它被用作函数参数的类型:

void foo(const void *const e)

    e = NULL; // compile-time error because of the second const
    char *s = e; // compile-time error because of the first const
    const char *t = e; // OK

...
char x[] = "test";
foo(x); // you can be confident that foo will not modify the contents

对于常规用法,这是不切实际的,因为第一个 const 表示无法修改取消引用的值,但无论如何都不能取消引用 void 指针。第二个const 本质上不允许您在初始化后重新分配指针。

【讨论】:

以上是关于C 中的泛型编程 - void*- const 正确性的主要内容,如果未能解决你的问题,请参考以下文章

C语言的泛型编程

什么意思 在HashMap之前 ? Java中的泛型[重复]

如何比较 C++ 中的泛型结构?

java中的泛型T和?的差异性,学习了

Java中的泛型 --- Java 编程思想

Java 中的泛型详解-Java编程思想