【问题标题】:Why are structs not allowed in equality expressions in C? [duplicate]为什么 C 中的等式表达式中不允许使用结构? [复制]
【发布时间】:2017-10-28 23:55:52
【问题描述】:

结构作为比较操作数的不可用性是 C 中最明显的事情之一,但对我来说没有太大意义。结构可以按值传递并通过赋值复制,但没有为它们指定==

以下是定义相等运算符(==!=)和简单赋值运算符(=)约束的 C11 标准(草案)的相关部分。请注意相等运算符的约束中缺少结构和联合。 (除了没有处理_Atomic之外,C99中的措辞是一样的)。

6.5.9 等式运算符

约束

应满足以下条件之一:

  • 两个操作数都有算术类型;
  • 两个操作数都是指向兼容类型的合格或不合格版本的指针;
  • 一个操作数是指向对象类型的指针,另一个是指向限定或非限定版本的 void 的指针;或
  • 一个操作数是一个指针,另一个是一个空指针常量。

6.5.16.1 简单赋值

约束

应满足以下条件之一:

  • 左操作数具有原子、合格或非限定算术类型,右操作数具有算术类型;
  • 左操作数具有与右操作数兼容的结构或联合类型的原子、限定或非限定版本;
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑到左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且由left 具有 right 指向的类型的所有限定符;
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后的类型)一个操作数是指向对象类型的指针,另一个是指向限定或非限定类型的指针void 的非限定版本,left 指向的类型具有 right 指向的类型的所有限定符;
  • 左边的操作数是一个原子的、合格的或不合格的指针,右边是一个空指针常量;或
  • 左操作数的类型为 atomic、qualified 或 unqualified _Bool,右操作数是指针。

谁能解释为什么存在这种差异(无需推测)?

【问题讨论】:

  • 唯一能不假思索地回答你的人是 Brian Kernighan
  • 嗯,是的,但他可能在前一段时间已经解释过了……而且这方面的证据可能很难挖掘,但这基本上就是我想看到的。由 K 或 ISO 委员会中的某个人提出的推理,如果它曾经在那里讨论过(不一定是 他们亲自在 SO :D 上讨论的)。 K&R 中有关于这个问题的任何内容吗? - 抱歉重复的顺便说一句:由于相等/比较差异,它没有出现在我的搜索中(我的是官方措辞:P)。
  • @M.M 无需纠缠 Kernighan 先生(反正他并没有参与 C 的第一次创建),咨询 C 的基本原理就足够了:stackoverflow.com/a/47056810/584518

标签: c standards c99 c11


【解决方案1】:

即使允许对这些类型进行赋值,也无法比较结构和联合的相等性。由对齐限制引起的结构和联合中的间隙可能包含任意值,并且对此进行补偿将对相等比较或所有修改结构和联合类型的操作带来不可接受的开销。

来自“C:参考手册”。即使memcmp 在比较结构时也会失败,原因相同(编译器为对齐目的添加了额外的缓冲区空间)。我想他们可以实现逐个成员的比较;为什么他们没有是另一个问题

【讨论】:

  • 使用代码a == b 可能会生成数千字节的汇编,这违背了 C 最初的极简主义性质;尽管随着编程环境的发展,未来可能会添加一些内容
  • 是的,没有实现逐个成员比较和其他结构比较方式的原因可以合理猜测。 OP 说“没有推测”,所以我只是坚持事实:)
  • @M.M:“极简主义”仅涉及编译器编写者的义务。因为如果用户必须比较结构,那么她不能只是避免它,而是必须手动编写代码来生成“千字节的汇编”,最终的应用程序可能比使用自动生成的代码更加臃肿(编译器知道差距确切地说 - 用户没有!)。但这很可能是该决定背后的原因——我只是希望得到比这更正式的确认。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 2018-10-09
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多