【问题标题】:Why can't a modifiable lvalue have an array type?为什么可修改的左值不能有数组类型?
【发布时间】:2017-08-13 00:52:17
【问题描述】:

来自 C11 标准(第 6.3.2.1 节左值、数组和函数指示符):

可修改的左值是一个左值 没有数组类型,没有不完整的类型,没有 const 限定 类型,如果它是结构或联合,则没有任何成员(包括, 递归地,所有包含的聚合或联合的任何成员或元素)具有 const 限定 输入。

简而言之,来自 C:

可修改的左值是未声明为 const 的左值 -qualified “Type Qualifiers”(第 180 页)),并且没有数组类型

可修改的左值不能有数组类型的原因是什么?

数组类型的对象总是隐含的 const 吗?

【问题讨论】:

  • 您可以分配给可修改的左值;您不能分配给数组(仅分配给数组的元素),因此数组名称不能是可修改的左值。
  • 谢谢。函数名是否具有与数组名相似的行为?但是函数名不是左值或非左值。 lvalue 和 nonlvalue 只能是对象表达式。
  • 在某些方面,函数名就像一个数组名;你当然不能指定一个函数名——但你可以用它来调用一个函数或初始化一个函数指针。 'modifiable lvalue' 这个名字的意义在于你可以在赋值中使用lvalue = rvalue;
  • 这是一个不可修改的左值。该标准在第 6.3.2.1 节的脚注 64 中提到了一次“右值”:有时称为“右值”在本国际标准中被描述为“表达式的值”。它还指定(引用前的几句话)一个通用左值:评估对象时,行为未定义。脚注 64 还说左值可以是:…被视为表示对象“定位器值”。
  • 没有非常深刻的原因;这只是语言设计者的选择。很可能是因为分配数组的成本可能很高,他们不希望这种成本“默默地”累积。但那是猜测。您可以通过使数组成为结构的成员然后分配 那些 左值来简单地分配数组。

标签: c language-lawyer


【解决方案1】:

C 语言的设计者认为不可能按值分配数组。在当时,这似乎是一个明智的决定(1970 年代初期)——内存和处理器速度非常有限,他们认为让 a = b; 使 ab 都引用同一个数组会更有意义比使用a = b; 将一个数组的内容复制到另一个数组的共同意图。

事实上,这已经很常见了:在 B 编程语言(C 的前身)中,int a[10]; 的等价物实际上意味着分配一个指针和一个 10 个整数的块,并将指针指向块10 个整数。你实际上可以在 B 的其他地方创建一个数组“点”。

C 改变了数组定义的含义,它只分配整数块;并添加了“规则”:当您在赋值表达式(和大多数其他表达式)中使用数组的名称时,数组会隐式转换为指向第一个元素的指针。因此,如果a 是一个指针而b 是一个数组,那么您仍然可以编写a = b; 以使a 的行为类似于b 的别名。虽然你不能再拥有a = b;,其中a 是一个数组。

在 1989 年的第一个 ANSI C 标准中,他们增加了按值复制结构的能力(这在以前的一些编译器中已经存在,但不是通用的),推论如果结构包含数组,那么数组就会被复制按价值。但是现在回过头来改变a = b;的含义来按值复制数组已经太晚了,写了太多已经依赖于规则的代码。

参考: The Development of the C Language - Dennis M. Ritchie

【讨论】:

    猜你喜欢
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 2011-08-23
    • 1970-01-01
    • 2018-01-22
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多