【问题标题】:Why may there be a difference between union* and struct*?为什么 union* 和 struct* 之间可能存在差异?
【发布时间】:2014-06-19 18:17:36
【问题描述】:

C 标准要求所有指向 unions 的指针具有相同的表示和对齐要求。
它要求所有指向structs 的指针都相同。

因此我的问题是:
为什么标准不要求指向 unions 的指针与指向 structs 的指针具有相同的表示和对齐要求?(我非常愿意欣赏利用这一点的实现示例。)
还是我只是错过了相关的文字?

标准草案n1570(C11最终草案)的相关引用:

6.2.5 类型§ 28

指向void 的指针应具有与 指向字符类型的指针。48) 同样,指向合格或不合格版本的指针 兼容类型应具有相同的表示和对齐要求。 全部 指向结构类型的指针应具有相同的表示和对齐要求 作为彼此。所有指向联合类型的指针都应具有相同的表示形式和 对齐要求。指向其他类型的指针不必相同 表示或对齐要求。

【问题讨论】:

  • 这难道不是您不能强制指向int 的指针与指向char 的指针具有相同的表示和对齐要求的原因吗?
  • @Amir:还有更多内容。看我的回答。
  • 顺便说一句:给这个时间,也许有人想出了一个非常模糊的实现,一些被遗忘已久的委员会讨论或其他同样具有启发性/令人惊讶的东西。
  • @Deduplicator:当谈到 C89 时,委员会甚至没有明确提到它(“所有指向结构/联合类型的指针”)作为要求。这种“添加”的原因被认为是指向不完整类型的单独翻译单元的指针。在我的最新问题中,我提供了很多与此要求相关的信息。

标签: c pointers struct language-lawyer unions


【解决方案1】:

1989 ANSI C RationaleISO C99 Rationale 都没有讨论这个问题。

我怀疑没有这样的要求有什么充分的理由。可能委员会不想强加不必要的严格要求。我也怀疑是否存在任何指向结构的指针和指向联合的指针具有相同表示的实际实现。

例如,考虑一个结构可以包含单个联合成员,反之亦然,因此实现可能没有充分的理由使用不同的表示 - 标准也没有任何充分的理由要求所有实现使用相同的表示。

所有结构指针“闻起来都一样”的原因是允许使用指向不完整类型的指针。例如:

struct foo;

void func(struct foo *param);

struct foo { /* member declarations */ };

编译器不需要知道任何关于struct foo 的信息,只要知道它是struct 类型就可以知道如何生成对func() 的调用。

这同样适用于不完整的联合类型。但是不完整的结构类型不能作为联合完成,反之亦然,因此能够假设它们具有相同的表示并没有太大的好处。

【讨论】:

  • 如果你说的对结构和联合指针使用不同的表示+对齐要求没有任何好处,那么强制没有区别有一个好处:为程序员提供更强的保证,这可能使他可以确保他的程序严格符合并因此具有高度可移植性,从而进行更广泛的更改。 (即使有变通方法,直接和明确更好......)
  • @Deduplicator:委员会必须考虑是否有理由使用他们没有想到的不同表示。标准中的每个要求对所有实施者都有潜在的非零成本。强制联合和结构指针使用相同表示的优点并不重要。
  • @Deduplicator:如果委员会遵循您描述的逻辑,我们所知道的 C 将不复存在。程序员已经有了最强有力的保证:指向结构的指针不需要与指向联合的指针相同。你问的不是保证,你问的是一个狭义的定义,这不是一回事。严格遵守和可移植,就是要遵守规则。你的建议是通过应用狭窄的定义来改变规则,这绝对不是 C 的方式。
  • 是否允许编译器为structs 施加任意最小对齐,也许是为了使此类指针在字寻址机器上更有效?这将导致struct- 和union-pointers 之间存在显着差异。
【解决方案2】:

尽管标准不要求实现这样做,但实现者可能会认识到拥有一种指针类型的有用性,该指针类型可能具有不同对齐要求的几种类型中的任何一种(例如uint8_tuint16_t、@ 987654323@, 和uint64_t),但只需要符合实际用于访问的类型的对齐方式(例如,用于访问uint16_t 时只需16 位对齐)。使用联合类型的指针来访问实际上不是联合类型的对象的东西可能看起来很奇怪,但是 C 没有提供其他语法来建议除了使用的实际类型之外,可以使用指针来为某些特定类型的东西起别名供访问。

如果系统使用单词地址,可以合理地说所有结构都将填充到整数个单词,并且必须在单词边界上对齐,但是对联合强加这样的要求会使它们无法使用为上述目的。因此,在这样的系统上,允许指向联合的指针来识别单个字节边界的位置(当 直接 只访问对齐会令人满意的东西时)可能是有意义的,即使指向结构的指针是仅限于字边界,即使这可能导致联合指针大于结构指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2015-02-12
    • 1970-01-01
    • 2011-11-14
    • 2021-11-03
    相关资源
    最近更新 更多