【问题标题】:Why is _Alignof missing from the rule about converting an array to a pointer?为什么将数组转换为指针的规则中缺少 _Alignof?
【发布时间】:2018-08-11 21:16:24
【问题描述】:

C 2011(草案 N1570)6.3.2.1 3 说:

除非它是 sizeof 运算符、_Alignof 运算符或一元 & 运算符的操作数,或者是字符串文字用于初始化数组,类型为 ''array of type'' 的表达式被转换为类型为 ''pointer to type'' 的表达式,它指向数组对象的初始元素,不是左值。如果数组对象有注册存储类,则行为未定义。

C 2018 6.3.2.1 3 说:

除非它是 sizeof 运算符的操作数,或一元 & 运算符,或者是用于初始化数组的字符串字面量,具有类型的表达式"array of type" 被转换为类型为 "pointer to type" 的表达式,它指向数组对象的初始元素并且不是左值。如果数组对象有注册存储类,则行为未定义。

为什么后者缺少_Alignof

C 2018 前言 7 说:

此版本没有大的变化,只是技术上的更正和澄清。

这意味着从数组转换规则中排除 _Alignof 存在一些错误,导致它被删除。但是,应该可以将 _Alignof 应用于数组,正如 C 2018 6.5.3.4 3 所说:

_Alignof 运算符产生其操作数类型的对齐要求。不计算操作数,结果是一个整数常量。当应用于数组类型时,结果是元素类型的对齐要求。

【问题讨论】:

  • 对于我偶然遇到的问题,这是一个非常好的问题。 - 恕我直言,委员会应该提供一个附录,至少用几句话来澄清在任何新标准版本中所做的所有更改。

标签: c language-lawyer


【解决方案1】:

在 C11 和 C18 标准中,_Alignof 运算符可以将类型名称作为操作数,但不能作为表达式。来自§6.5.3 of the C11 Draft Standard:

Syntax

      unary-expression:
             postfix-expression
             ++ unary-expression
             -- unary-expression
             unary-operator cast-expression
             sizeof unary-expression
             sizeof ( type-name )
             _Alignof ( type-name )
      unary-operator: one of
             & * + - ~ !

sizeof 运算符可以使用表达式或带括号的类型名称作为操作数,但由于使用带括号的类型名称以外的任何内容作为 _Alignof 的参数是违反约束的,因此根本没有这里需要数组转换的特殊例外。


事实证明,在 N1570 草案标准的发布和 C11 标准的最终版本 (ISO/IEC 9899:2011) 之间发生了变化。 this SO answer 中有一些讨论,引用了this Google Groups thread 中的讨论,其中 ISO C 委员会的 Larry Jones 建议:

最大的变化是将 _Alignof 从 一堆不应该添加的地方(基于错误的 认为它需要一个类型或一个像sizeof 这样的表达式 当它真的只需要一个类型时):6.3.2.1p2,p3,p4,fn。 65;和 6.7.1 fn。 121.

【讨论】:

  • 很好的答案。我想知道为什么委员会从未在任何地方明确提及更改该段落的原因。
  • @RobertSsupportsMonicaCellio -- 好问题;我没有注意到这个修订实际上发生在 C11 草案标准发布和最终发布之间。我已经用一些额外的信息更新了我的答案。
猜你喜欢
  • 2019-03-11
  • 2015-03-26
  • 2020-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多