【发布时间】:2021-04-15 12:01:13
【问题描述】:
我一直在阅读一些关于 void* 类型指针的文章,并从标准中找到了这个要求。
6.2.5.27:
指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。39) 同样,指向兼容类型的合格或非合格版本的指针应具有相同的表示和对齐要求。
我看到标准不保证所有指针类型都具有相同的长度,所以这里的底线是void* 指针具有与char* 相同的长度和对齐规则,对吧?
我没有得到的是脚注 39),它说
相同的表示和对齐要求意味着作为函数的参数、函数的返回值和联合成员的可互换性。
我的问题是:
-
“可互换性”是什么意思?是不是说函数
void* Func(void*)的参数和返回值都可以是char*? -
如果是,是否是编译器进行的隐式转换?
-
工会成员是怎么回事?我真的不明白这句话的意思。谁能给我一个简单的例子?
【问题讨论】:
-
不详述,意思是指针就是指针就是指针。在 C 中,任何类型的指针都可以分配给
void*并返回而无需强制转换。这是可互换性的基础。不会发生隐式转换,void*指针只是一个没有特定类型的指针。而且,由于类型控制指针运算,您不能对void*指针进行指针运算。就像您不能取消引用void*指针一样,因为缺少类型信息——这将是一个不完整的类型。所以你必须在引用之前分配或转换一个 void 指针。 -
@DavidC.Rankin 这些都是真实的陈述,但我不认为它们是引用的段落的内容。这是关于
void*和char*具有相同的表示。void*不必具有与其他指针类型相同的表示或对齐方式。 -
我认为这意味着它们的大小相同并且具有相同的对齐要求。 (这也与严格的别名规则-类型兼容和
char*例外相吻合)我没有对标准部分进行批判性解释,只是更实际地讨论了该部分如何不包含任何隐藏的陷阱。跨度> -
我通常认为这是一个标准,即这些可互换类型是“兼容”的,目的是满足函数调用要求,但放弃将其转化为规范的官方语言。例如,您可以在一个翻译单元中定义
void *foo(void *p),并在另一个翻译单元中声明char *foo(char *p),然后使用后者调用它,因为类型是可互换的,所以它会起作用。但根据 C 标准的规范文本,它是未定义的,除了 C 2018 6.2.5 28 中的这段关于相同的表示。 -
该问题将段落引用为 6.2.5.27,我认为这意味着第 6.2.5 条第 27 段(您不应使用该格式,因为它无法区分第 6.5 条第 1 段和第 6.5.1 条) ,但我在任何官方版本的C标准中都没有找到6.2.5 27。 1999 年是第 26 段。2011 年是第 28 段(虽然我在看 2011 年的草稿,但我认为这是发布前的最后一个)。
标签: c language-lawyer void-pointers