为什么字符串文字是 l- 值而其他文字都是 r- 值?

C + + 035.1主表达式2 表示:

字面值是主要表达式。它的类型取决于它的形式(2.13)。字符串文字是左值; 所有其他文字都是右值。

同样,C996.5.14表示:

字符串文字是一个主表达式,它是一个左值,类型详见6.4.5。

这背后的理由是什么?

据我所知,字符串文字是对象,而所有其他文字不是。L 值总是指一个对象。

但问题是为什么字符串文字是对象而其他文字不是?这个逻辑在我看来更像是鸡蛋或鸡肉的问题。

我知道这个问题的答案可能与硬件架构有关,而不是 C/C + + 作为编程语言,尽管如此,我还是希望听到同样的答案。

10007 次浏览

字符串文字是一个带有数组类型的文字,在 C 中,数组类型只能以左值的形式存在于表达式中。字符串文字可以指定指针类型(而不是通常衰减为指针的数组类型)指向字符串“ content”,但是这会使它们不太有用; 特别是,sizeof操作符不能应用于它们。

注意,C99引入了复合文字,它们也是 lvalue,因此将文字设为 lvalue 不再是一个特殊的例外; 它更接近于规范。

我猜最初的动机主要是实用主义的: 一个字符串 字符串必须驻留在内存中并有一个地址 文字是一个数组类型(C 中的 char[],C + + 中的 char const[]) ,以及 数组类型在大多数上下文中转换为指针 已经找到了其他方法来定义它(例如,字符串文字可以具有 指针类型开头,有关它的内容的特殊规则 指向) ,但是仅仅将字面值设置为左值可能就是 定义什么是具体需要的最简单的方法。

C + + 中的 lvalue并不总是引用对象。它也可以引用一个函数。此外,对象不必由 lvalues引用。它们可以由 rvalues引用,包括用于数组(在 C + + 和 C 中)。但是,在旧的 C89中,数组到指针的转换不适用于 rvalues数组。

现在,rvalue表示没有、有限或即将过期。但是,字符串文字对于整个程序是有效的。

所以 string literals就是 lvalues完全正确。

字符串文字是 数组-具有固有的不可预测大小的对象(即用户定义的、可能大的对象)。在一般情况下,除了在内存中作为对象(即 lvalues)之外,没有其他方法可以表示这样的文字。在 C99中,这也适用于 复合文字,它也是 lvalues

任何试图人为地隐藏字符串文字在语言层次上是 lvalues的事实都会产生相当多的完全不必要的困难,因为用指针指向字符串文字的能力以及以数组形式访问它的能力严重依赖于它在语言层次上的左值可见性。

同时,标量类型的文字具有固定的编译时大小。同时,这样的文字很可能直接嵌入到给定硬件架构上的机器命令中。例如,当您编写类似于 i = i * 5 + 2的代码时,字面值 52将成为生成的机器代码的显式(甚至隐式)部分。它们不存在,也不需要作为独立位置存在于数据存储中。在数据内存中存储值 52根本没有意义。

同样值得注意的是,在许多(如果不是大多数或全部)硬件架构上,浮点文字实际上是作为“隐藏的”lvalues实现的(即使该语言没有这样公开它们)。在像 x86这样的平台上,来自浮点组的机器命令不支持嵌入的即时操作数。这意味着编译器实际上必须将每个浮点文本存储在数据内存中(并从中读取)。例如,当你写像 i = i * 5.5 + 2.1这样的东西时,它被翻译成

const double unnamed_double_5_5 = 5.5;
const double unnamed_double_2_1 = 2.1;
i = i * unnamed_double_5_5 + unnamed_double_2_1;

换句话说,floating-point literals常常在内部变成“非官方的”lvalues。然而,语言规范并没有尝试公开这个实现细节,这是非常有意义的。在语言层面上,arithmetic literals作为 rvalues更有意义。