C标准规定所有指向union
的指针都具有相同的表示和对齐要求
对于struct
s的所有指针,它都要求相同。
因此我的问题:
为什么标准不强制指向union
的指针具有与指向struct
的指针相同的表示和对齐要求?(我非常欣赏实现的示例利用这一点。)
或者我只是错过了相关的文字?
标准草案n1570(C11最终草案)的相关引用:
6.2.5类型§28
指向
void
的指针应具有与a相同的表示和对齐要求 指向字符类型的指针。 48)同样,指向合格或非限定版本的指针 兼容类型应具有相同的表示和对齐要求。 所有 指向结构类型的指针应具有相同的表示和对齐要求 彼此相同。所有指向联合类型的指针都应具有相同的表示形式 对齐要求彼此。指向其他类型的指针不必相同 表示或对齐要求。
答案 0 :(得分:5)
1989 ANSI C Rationale和ISO C99 Rationale均未对此进行讨论。
我怀疑是否存在缺乏此类要求的充分理由。可能委员会并不想强加不必要的严格要求。我还怀疑是否存在任何实际的实现,其中指向结构的指针和指向 don&#t> 的联合的指针具有相同的表示。
例如,考虑一个结构可以包含一个联合成员,反之亦然,因此可能没有充分的理由让实现使用不同的表示 - 标准也没有任何合理的理由要求所有实现使用相同的表示。
所有结构指针"气味相似的原因"是允许使用指向不完整类型的指针。例如:
struct foo;
void func(struct foo *param);
struct foo { /* member declarations */ };
除了struct foo
类型之外,编译器不必知道struct
的任何内容,以了解如何生成对func()
的调用。
同样适用于不完整的联合类型。但是不完整的结构类型不能作为联合完成,反之亦然,因此能够假设它们具有相同的表示没有很大的好处。
答案 1 :(得分:0)
即使标准不要求实现这样做,实现者也可能认识到使用一种指针类型的有用性,该指针可能是具有不同对齐要求的几种类型中的任何一种的别名(例如uint8_t
,{{1 }},uint16_t
和uint32_t
),但只需要符合实际用于访问的类型的对齐(例如,当用于访问uint64_t
时,只需要16位对齐)。使用联合类型的指针来访问实际上不是联合类型对象的东西可能看起来很奇怪,但是C没有提供任何其他语法来建议除了实际的指针之外还可以使用指针来对某些特定类型的东西进行别名用于访问的类型。
如果系统使用字地址,则可以合理地说所有结构都将填充到整数字并且必须在字边界上对齐,但是对工会强加这样的要求会使它们无法使用它们出于上述目的。在这样的系统上,可能因此允许指向联合的指针来识别单个字节边界处的位置(当直接仅访问对齐将令人满意的事物时),即使指向结构的指针将是限于字边界,即使这可能导致联合指针大于struct指针。