72

C++03 5.1 主要表达式 §2说:

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

同样,C99 6.5.1 §4说:

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

这背后的原因是什么?

据我了解,字符串文字是对象,而所有其他文字都不是。l 值总是指一个对象。

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

我知道这个问题的答案可能与硬件架构有关,而不是与 C/C++ 作为编程语言有关,但我想听听同样的。

4

4 回答 4

37

字符串字面量是具有数组类型的字面量,在 C 中,数组类型除了作为左值之外,无法在表达式中存在。可以将字符串文字指定为具有指向字符串“内容”的指针类型(而不是通常衰减为指针的数组类型),但这会使它们的用处不大;特别是,sizeof运算符不能应用于它们。

请注意,C99 引入了复合文字,它们也是左值,因此让文字成为左值不再是一个特殊的例外;它更接近于常态。

于 2012-04-04T03:34:03.607 回答
17

字符串字面量是数组- 本质上不可预测大小的对象(即用户定义的并且可能很大的大小)。在一般情况下,除了作为内存中的对象(即lvalues. 在 C99 中,这也适用于复合文字,它们也是lvalues.

任何人为地隐藏字符串文字处于语言级别这一事实的尝试lvalues都会产生大量完全不必要的困难,因为使用指针指向字符串文字的能力以及作为数组访问它的能力至关重要它的左值性在语言级别上是可见的。

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

还值得注意的是,在许多(如果不是大多数或全部)硬件架构上,浮点文字实际上是作为“隐藏的”实现的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

于 2012-12-06T01:40:15.417 回答
10

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

现在,anrvalue表示没有、有限或即将过期。然而,字符串文字存在于整个程序中。

所以string literals存在lvalues是完全正确的。

于 2012-04-04T08:00:25.057 回答
10

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

于 2012-04-04T07:38:33.360 回答