为什么string文字l值而所有其他文字是r值?

C ++ 03 5.1主expression式
§2:

一个文字是一个主要的expression。 它的types取决于它的forms(2.13)。 一个string文字是一个左值; 所有其他文字是rvalues。

这背后的理由是什么?
据我所知,string文字是对象,而所有其他文字不是。而且一个l值总是指一个对象。

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

我理解这个答案可能与硬件架构有关,而不是C / C ++作为编程语言,不过我希望听到同样的答案。

注意:我将这个问题标记为c&c ++,因为C99标准也有类似的引用,特别是§6.5.1.4

一个string文字是一个数组types的文字,而在C中,数组types不能在expression式中存在,除非作为左值。 string文字可能被指定为具有指向string“contents”的指针types(而不是数组types,通常衰减为指针),但是这会使它们不那么有用; 特别是运营商的sizeof不能适用于他们。

请注意,C99引入了复合文字,也是左值,所以文字是一个左值不再是一个特殊的例外; 这更接近于规范。

C ++中的左值并不总是指向一个对象。 它也可以引用一个函数。 而且,对象不必被左值引用。 它们可能被rvalues引用,包括数组(用C ++和C)。 不过在旧的C89中,数组到指针的转换并不适用于右值数组。

现在,右值表示没有,有限或即将过期的生命期。 string字面意味着整个程序。

所以string的左值是正确的。

我猜想原来的动机主要是一个实用的动机:一个string文字必须驻留在内存中,并有一个地址。 string文字的types是一个数组types(C中的char const[] ,C ++中的char const[] ),数组types在大多数上下文中转换为指针。 这个语言本来可以find其他的方式来定义它(例如,一个string字面值可以有指针types开始,特殊的规则是关于它指向什么的),但是把字面值设为左值可能是定义具体的最简单的方法需要。

string文字是数组 – 具有固有不可预知的大小(即用户定义的和可能的大尺寸)的对象。 在一般情况下,除了存储器中的对象(即左值)之外,没有其他方法可以表示这些文字。 在C99中,这也适用于复合文字 ,也是左值。

任何人为地隐藏string文字在语言层次上是左值的事实将会产生相当多的完全不必要的困难,因为指向string文本和指针的能力以及作为数组访问它的能力依赖于关键在于语言层面的可见性。

同时,标量types的文字具有固定的编译时间大小。 同时这些文字很可能被直接embedded给定硬件体系结构的机器命令中。 例如,当您编写类似于i = i * 5 + 2 ,文字值52变成生成的机器代码的显式(甚至隐式)部分。 它们不存在,不需要在数据存储中作为独立的位置存在。 在数据存储器中存储值52是没有意义的。

在许多(如果不是大多数或全部)硬件体系结构浮点文字实际上被实现为“隐藏的”左值(即使语言不暴露它们)也是值得的。 在来自浮点组的x86机器命令等平台上不支持embedded的立即操作数。 这意味着实际上每个浮点文字都必须被编译器存储在数据存储器中(并从中读取)。 例如,当你写这样的东西像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; 

换句话说,浮点文字通常最终会在内部变成“非官方”的左值。 但是,语言规范并没有试图公开这个实现细节,这是非常有意义的。 在语言层面,算术文字作为右值更有意义。