C++03 5.1 Primary expressions §2说道:
文字是一个主表达式。它的类型取决于它的形式(2.13)。字符串文字是一个左值;所有其他文字都是右值。
同样,C99 6.5.1 §4规定:
字符串文字是一个主表达式。它是一个左值,其类型详见6.4.5。
这背后的理由是什么?
据我所知,字符串文字是对象,而所有其他文字都不是。并且l值总是引用对象。
但问题是为什么字符串文字是对象而所有其他文字不是?这个基本原理在我看来更像是一个蛋还是鸡的问题。
我知道这个问题的答案可能与硬件架构有关,而不是C/C++作为编程语言,尽管如此,我还是希望听到同样的答案。
5条答案
按热度按时间efzxgjgh1#
一个字符串文字是一个数组类型的文字,在C语言中,除了左值之外,数组类型不可能存在于表达式中。字符串文字可以被指定为指向字符串“内容”的指针类型(而不是通常衰减为指针的数组类型),但这会使它们变得不那么有用;特别是,
sizeof
运算符不能应用于它们。注意,C99引入了复合文字,它们也是左值,所以文字是左值不再是一个特殊的例外;它更接近于常态。
gdx19jrr2#
字符串字面量是 * 数组 * -具有固有的不可预测大小的对象(即用户定义的,可能很大的大小)。在一般情况下,除了作为内存中的对象,即
lvalues
之外,没有其他方法来表示此类字面量。在C99中,这也适用于 * 复合字面量 *,也是lvalues
。任何人为地隐藏字符串字面量在语言级别上是
lvalues
的事实的尝试都会产生相当多的完全不必要的困难,因为用指针指向字符串字面量的能力以及作为数组访问它的能力严重依赖于它的左值在语言级别上是可见的。同时,标量类型的字面量具有固定的编译时大小。同时,这样的字面量很可能直接嵌入到给定硬件架构上的机器命令中。例如,当您编写类似
i = i * 5 + 2
的代码时,文字值5
和2
变为显式它们不存在,也不需要作为数据存储中的独立位置存在。在数据存储器中存储值5
和2
根本没有意义。值得注意的是,在许多(如果不是大多数,或全部)硬件体系结构浮点字面值实际上实现为“隐藏”
lvalues
在像x86这样的平台上,来自浮点组的机器命令不支持嵌入的立即操作数。这意味着实际上每个浮点文字都必须存储在例如,当你写i = i * 5.5 + 2.1
这样的代码时,它会被翻译成这样的代码换句话说,
floating-point literals
通常最终在内部成为“非官方”的lvalues
。然而,语言规范没有尝试公开此实现细节是完全合理的。在语言级别,arithmetic literals
更有意义为rvalues
。62o28rlo3#
我想最初的动机主要是实用主义的:字符串文字必须驻留在内存中并具有地址。字符串文字的类型是数组类型(C中的
char[]
,C++中的char const[]
),数组类型在大多数上下文中转换为指针。(例如,字符串文字可以以指针类型开始,具有关于它指向什么的特殊规则),但是仅仅将文字作为左值可能是定义具体需要的最简单的方法。4urapxun4#
C中的
lvalue
并不总是引用对象。它也可以引用函数。此外,对象不必被lvalues
引用。它们可以被rvalues
引用,包括数组(在C和C中)。然而,在旧的C89中,数组到指针的转换并不适用于rvalues
数组。现在,
rvalue
表示没有、有限或即将过期的生存期。然而,字符串文字适用于整个程序。所以
string literals
是lvalues
是完全正确的。mi7gmzs65#
答案和评论中有很多有价值的信息。有几点值得强调。
数组可以是右值。更多信息可以在here和here中找到。例如,以下代码涉及右值数组:
因此,不好推断字符串文字是数组,因为它们是左值。
最好记住字符串字面值在程序的生命周期内持续存在。即使value category is not lifetime,也可以根据它们的生命周期来理解为什么字符串字面值是左值。
就像many关于值类别的讨论一样,字符串字面量是左值,这在很大程度上是由关于语言发展到目前为止发生了什么以及从我们当时的立场可以做的最好的事情的务实考虑所驱动的。