string literal是一个左值;其他文字是右值。 [英] string literal is an lvalue; other literals are rvalues.

查看:64
本文介绍了string literal是一个左值;其他文字是右值。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是来自标准的上一版本的草稿:

http://www.kuzbass.ru:8086/docs/isocpp/expr.html


2-字面值是主要表达。它的类型取决于它的形式

(lex.literal)。字符串文字是*左值*;所有其他文字都是

* rvalues *。


-4-运算符::后跟一个标识符,一个限定id或一个

operator-function-id是一个主表达式。它的类型由标识符,qualified-id或operator-function-id的

声明指定。

结果是由标识符,qualified-id或

operator-function-id表示的实体。如果实体是函数

或变量,则结果为*左值*。标识符,qualified-id或operator-function-id应该具有全局命名空间范围,或者在全局范围内可见,因为使用了指令(namespace.udir)
)。 [注意:使用::允许在全局

命名空间中声明的类型,

对象,函数,枚举器或命名空间被引用如果它的标识符已被隐藏

(basic.lookup.qual)。 ]


我理解rvalue和左值之间的区别,左值*可以*

出现在表达式的左侧,而右值可以*只有*

出现在右侧。我不太了解的是


1)谁在乎呢?我的意思是,为什么指定这么重要?


我认为这是通过指定左值来定义语法规则的一种方式

可以去这里,但不是rvalues等。但这看起来像鸡和鸡蛋几乎是鸡蛋。在4.1中有关于左值转换的左值的讨论。那是

只是一个概念手段,还是编译器实际做的事情?


2)我不知道为什么函数或字符串文字会被认为是一个

左值。


在函数的情况下是因为它可以是一个独立的语句?或者是

是因为它可以出现在左边的纯虚拟声明中

的''=''一边?


-

STH

哈顿定律:只有一个不可侵犯的法律

KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com

Mozilla: http://www.mozilla.org

This is from the draft of the previous version of the Standard:

http://www.kuzbass.ru:8086/docs/isocpp/expr.html

2- A literal is a primary expression. Its type depends on its form
(lex.literal). A string literal is an *lvalue*; all other literals are
*rvalues*.

-4- The operator :: followed by an identifier, a qualified-id, or an
operator-function-id is a primary-expression. Its type is specified by the
declaration of the identifier, qualified-id, or operator-function-id. The
result is the entity denoted by the identifier, qualified-id, or
operator-function-id. The result is an *lvalue* if the entity is a function
or variable. The identifier, qualified-id, or operator-function-id shall
have global namespace scope or be visible in global scope because of a
using-directive (namespace.udir). [Note: the use of :: allows a type, an
object, a function, an enumerator, or a namespace declared in the global
namespace to be referred to even if its identifier has been hidden
(basic.lookup.qual). ]

As I understand the distinction between rvalue and lvalue, an lvalue *can*
appear on the left side of an expression, whereas an rvalue can *only*
appear on the right side. What I don''t fully understand is

1) who cares? What I mean to ask is, why is it so important to specify?

I assume it''s a way of defining the syntax rules by specifying that lvalues
can go here, but not rvalues, etc. But this seems like the chicken and the
egg almost. There is talk of lvalue to rvalue conversion in 4.1. Is that
just a conceptual artifice, or something the compiler actually does?

2) I''m not sure why a function or a string literal would be considered an
lvalue.

In the case of a function is it because it can be a standalone statement? Or
is it because it can appear in a pure virtual declaration on the lefthand
side of the ''=''?

--
STH
Hatton''s Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org

推荐答案

*" Steven T. Hatton <苏****** @ setidava.kushan.aa> schriebt:
* "Steven T. Hatton" <su******@setidava.kushan.aa> schriebt:

正如我理解rvalue和左值之间的区别,左值*可以*
出现在表达式的左侧,而右值只能* * * br />出现在右侧。


如果他们不是表达的一部分。


另一个更有用的区别是你可以拿一个左值的地址,

但不是右值。


左值表示存储位置,右值表示无位置值,

如int值5.


因此,一个右值不能单独出现在

赋值的左侧,这就是它的基础术语。


但是这个术语有点误导:一个const值不能出现在作业左边的

左侧(虽然必须有一个

左值。

我不完全理解的是

1)谁在乎呢?我的意思是,为什么指定这么重要?


修改5的值的程序,比较难以调试。


我认为这是一种定义方式语法规则通过指定lvalues
可以到这里,但不是rvalues等。但这看起来像鸡和鸡蛋差不多。在4.1中有关于左值转换的左值的讨论。这仅仅是一个概念手段,还是编译器实际上做的事情?


我认为引用4.1中的相关段落是你的工作。


通常需要将左值转换为右值。例如。你可以使用int

变量,只要你可以使用int值,如5。相反的转换

当然是不允许的;例如你不能分配值5.

2)我不确定为什么函数或字符串文字会被认为是一个
左值。


功能:因为你必须能够使用它的地址才能使用

函数指针。


字符串文字:因为早期的C没有''const'',所以旧的C函数

将''char *''作为参数无法使用文字字符串调用

如果字符串文字被视为rvalues,则为实际参数。但是,

可能仍会改变。它只是一个旧的兼容性功能。


在函数的情况下是因为它可以是一个独立的语句?或者
是因为它可以出现在''=''左侧
侧的纯虚拟声明中?

As I understand the distinction between rvalue and lvalue, an lvalue *can*
appear on the left side of an expression, whereas an rvalue can *only*
appear on the right side.
If they''re not part of expressions.

Another more useful difference is that you can take the address of an lvalue,
but not of an rvalue.

An lvalue denotes a storage location, an rvalue denotes a value sans location,
such as the int value 5.

Thus, an rvalue cannot by itself appear on the left hand side in an
assignment, and that''s the basis of the terminology.

But the terminology is a bit misleading: a const lvalue can''t appear on the
left hand side of an assignment, either (although what''s there must be an
lvalue).
What I don''t fully understand is

1) who cares? What I mean to ask is, why is it so important to specify?
A program that modified the value of 5, say, would be difficult to debug.

I assume it''s a way of defining the syntax rules by specifying that lvalues
can go here, but not rvalues, etc. But this seems like the chicken and the
egg almost. There is talk of lvalue to rvalue conversion in 4.1. Is that
just a conceptual artifice, or something the compiler actually does?
I think it''s your job to quote the relevant passage in 4.1.

Converting an lvalue to rvalue is often necessary. E.g. you can use an int
variable wherever you can use an int value such as 5. The opposite conversion
is of course not allowed; e.g. you cannot assign to the value 5.
2) I''m not sure why a function or a string literal would be considered an
lvalue.
Function: because you must be able to take its address in order to use
function pointers.

String literal: because early C did not have ''const'', and so old C functions
that take ''char*'' as argument could not be called with literal strings as
actual arguments if string literals were considered rvalues. However, that
may still change. It''s just an old compatibility feature on its way out.

In the case of a function is it because it can be a standalone statement? Or
is it because it can appear in a pure virtual declaration on the lefthand
side of the ''=''?




否,见上文。


-

答:因为它弄乱了人们通常阅读文字的顺序。

问:为什么顶级发布这么糟糕?

A:热门发布。

问:usenet和电子邮件中最烦人的是什么?



No, see above.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Alf P. Steinbach写道:
Alf P. Steinbach wrote:
*" Steven T. Hatton" <苏****** @ setidava.kushan.aa> schriebt:
* "Steven T. Hatton" <su******@setidava.kushan.aa> schriebt:

正如我理解rvalue和左值之间的区别,左值
*可*出现在表达式的左侧,而右值可以
*只*出现在右侧。
如果他们不是表达的一部分。

另一个更有用的区别是你可以取一个
左值的地址,而不是右值。

左值表示存储位置,右值表示无值位置,例如int值5。

As I understand the distinction between rvalue and lvalue, an lvalue
*can* appear on the left side of an expression, whereas an rvalue can
*only* appear on the right side.
If they''re not part of expressions.

Another more useful difference is that you can take the address of an
lvalue, but not of an rvalue.

An lvalue denotes a storage location, an rvalue denotes a value sans
location, such as the int value 5.




如果我的源代码中有一个字面值5,那么它的起始字符为ascii

字符。这是由编译器翻译和使用的。要么产生一个结果以某种方式进入运行时的b / b
实例,或者它直接插入到运行时中,要么消耗
。例如,


const int x = 5 * 125; // 5被消耗并被遗忘


const int y = 5; // 5过着漫长而重要的生活


int f(const int& n){

返回5 * n; // 5必须在某个地方的阴影中留下来

}

因此,一个右值不能单独出现在
赋值的左侧,并且这是术语的基础。

但是这个术语有点误导:一个const值不能出现在任务的左侧(尽管如此)什么必须有一个左值。


我想有些困难在于我们正在讨论两个相同抽象问题空间的不同模型。一个是基于文本的

源代码,另一个是

存储中程序的运行时表示。当我读到你的声明时,const lvalue不会出现在作业的左边那边我觉得我理解并同意它。

然后我写了两个上面的例子。这是否意味着x和y仅在初始化(定义)后成为常量值?


我将授予我知道无法指定的权利在上面的

功能f中的5的位置,但它必须在运行时具有某种代表性

存储。我不确定它是否会归类为右值。我只是用它来试图让源代码的哪些部分找到它们进入运行时映像的方式,以及如何在那里表示它们。


我相信大约十年前我已经解开了这个东西。



If I have a literal 5 in my source code it begins life as an ascii
character. That is translated and used by the compiler. It is either
consumed to produce a result that somehow makes its way into the runtime
instance of the program, or it is directly inserted into the runtime. E.g.,

const int x = 5 * 125; // 5 is consumed and forgotten

const int y = 5; // 5 lives a long and significant life

int f(const int& n){
return 5 * n; // 5 has to stick around in the shadows somewhere
}
Thus, an rvalue cannot by itself appear on the left hand side in an
assignment, and that''s the basis of the terminology.

But the terminology is a bit misleading: a const lvalue can''t appear on
the left hand side of an assignment, either (although what''s there must be
an lvalue).
I guess some of the difficulty is that we are talking about two drastically
different models of the same abstract problem space. One is the text-based
source code, the other is the runtime representation of the program in
storage. When I read your statement that const lvalue can''t appear on the
lefthand side of an assignment I thought I understood and agreed with it.
Then I wrote the two examples above. Does this mean that x and y only
become const lvalues after they are initialized (defined)?

I will grant that I know of no way to specify the location of 5 in the
functon f above, but it has to have some kind of representaton in runtime
storage. I''m not sure if it would be categorize as an rvalue. I''m just
using it to try to get an undstanding of what parts of the source code find
their way into the runtime image, and how they are represented there.

I believe I undstood this stuff about ten years ago.

我不太了解的是
< 1)谁在乎呢?我的意思是,为什么指定这么重要?
一个修改了5的值的程序,比如说很难调试。
What I don''t fully understand is

1) who cares? What I mean to ask is, why is it so important to specify?
A program that modified the value of 5, say, would be difficult to debug.




同意。但我知道之前我知道它被称为rvalue。



Agreed. But I knew that before I knew it was called an rvalue.

我认为它是一种定义语法规则的方法指定
lvalues
可以到这里,但不是rvalues等。但这看起来像鸡和鸡蛋差不多了。在4.1中有关于左值转换的左值的讨论。这只是一个概念性手段,还是编译器实际做的事情?
I assume it''s a way of defining the syntax rules by specifying that
lvalues
can go here, but not rvalues, etc. But this seems like the chicken and
the
egg almost. There is talk of lvalue to rvalue conversion in 4.1. Is that
just a conceptual artifice, or something the compiler actually does?



我认为引用4.1中的相关段落是你的工作。



I think it''s your job to quote the relevant passage in 4.1.




这是一个比我之前在这个帖子中发布的链接更好的链接:
http://www.itga.com.au/~gnb/wp/cd2/


4.1左值到右值的转换[conv.lval]


1非函数非数组类型T的左值(_basic.lval_)可以是

转换为右值。如果T是一个不完整的类型,那么

的程序需要这种转换是不正确的。如果左值引用的对象
不是T类型的对象,并且不是从T派生的

类型的对象,或者如果对象未初始化,

的程序需要这种转换具有未定义的行为。如果T是非

否则,右值的类型为T. 1 )


2左值表示的对象中包含的值是

右值结果。当在sizeof(_expr.sizeof_)的

操作数内发生左值到右值转换时,不会访问refer-

nced对象中包含的值,因为运算符不评估

其操作数。

通常需要将左值转换为右值。例如。你可以使用一个
int
变量,只要你可以使用像5这样的int值。当然不允许使用相反的转换。例如你无法分配价值
5。



This is a better link than the one I posted previously in this thread:
http://www.itga.com.au/~gnb/wp/cd2/

4.1 Lvalue-to-rvalue conversion [conv.lval]

1 An lvalue (_basic.lval_) of a non-function, non-array type T can be
converted to an rvalue. If T is an incomplete type, a program that
necessitates this conversion is ill-formed. If the object to which
the lvalue refers is not an object of type T and is not an object of a
type derived from T, or if the object is uninitialized, a program that
necessitates this conversion has undefined behavior. If T is a non-
class type, the type of the rvalue is the cv-unqualified version of T.
Otherwise, the type of the rvalue is T. 1)

2 The value contained in the object indicated by the lvalue is the
rvalue result. When an lvalue-to-rvalue conversion occurs within the
operand of sizeof (_expr.sizeof_) the value contained in the refer-
enced object is not accessed, since that operator does not evaluate
its operand.
Converting an lvalue to rvalue is often necessary. E.g. you can use an
int
variable wherever you can use an int value such as 5. The opposite
conversion is of course not allowed; e.g. you cannot assign to the value
5.




但是说左值转换为右值对我来说并不重要。

在CPU中实际发生了什么事来改变对象的表示形式?
对象?另外,如果rvalue /是/对象,它有一个存储位置

不是吗?



But to say an lvalue is converted to an rvalue doesn''t mean much to me.
Does something actually happen in the CPU to change the representation of
the object? Also, if the rvalue /is/ an object, it has a storage location
doesn''t it?

2)我不确定为什么函数或字符串文字会被认为是一个
左值。
2) I''m not sure why a function or a string literal would be considered an
lvalue.



功能:因为你必须能够按顺序获取其地址使用
函数指针。

字符串文字:因为早期的C没有''const'',所以旧的C
函数将'char *''作为如果字符串文字被认为是rvalues,则无法使用文字
字符串调用参数作为实际参数。但是,
可能仍会改变。它只是一个旧的兼容性功能。



Function: because you must be able to take its address in order to use
function pointers.

String literal: because early C did not have ''const'', and so old C
functions that take ''char*'' as argument could not be called with literal
strings as
actual arguments if string literals were considered rvalues. However,
that
may still change. It''s just an old compatibility feature on its way out.




这里有一些我不想要的东西。

程序如何表示和处理与右值或左值相同的对象有什么区别?


-

STH

哈顿定律:只有一个不可侵犯的法律

KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com

Mozilla: http://www.mozilla.org



There''s something I''m missing here. What is the difference in how the
program represents and process the same object as an rvalue or an lvalue?

--
STH
Hatton''s Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org


*" Steven T. Hatton" <苏****** @ setidava.kushan.aa> schriebt:
* "Steven T. Hatton" <su******@setidava.kushan.aa> schriebt:
Alf P. Steinbach写道:
Alf P. Steinbach wrote:
*" Steven T. Hatton" <苏****** @ setidava.kushan.aa> schriebt:
* "Steven T. Hatton" <su******@setidava.kushan.aa> schriebt:

正如我理解rvalue和左值之间的区别,左值
*可*出现在表达式的左侧,而右值可以
*只*出现在右侧。
如果他们不是表达的一部分。

另一个更有用的区别是你可以取一个
左值的地址,而不是右值。

左值表示存储位置,右值表示无值位置,例如int值5。

As I understand the distinction between rvalue and lvalue, an lvalue
*can* appear on the left side of an expression, whereas an rvalue can
*only* appear on the right side.
If they''re not part of expressions.

Another more useful difference is that you can take the address of an
lvalue, but not of an rvalue.

An lvalue denotes a storage location, an rvalue denotes a value sans
location, such as the int value 5.




哎呀,这还不够通用。函数

std :: string foo(){return" Hey" ;; } $ / $
返回一个右值,因为临时对象是一个右值。你不能把它的地址带到

,因为从概念上讲它没有存储位置。但就

机器代码而言,在这种特殊情况下,如果你然后定义

void bar(std :: string const& s){std: :cout<< & s<<的std :: ENDL; }

并称之为

bar(foo());

该位置可以直接使用,如果是,那么''bar ''会显示它

(对象本身也有一个给出地址的函数)。


不,一个人不需要愚蠢为了不考虑这一点。


确切的规则是_very_复杂&朦胧,例如引起问题

在Andrei Alexandrescu的原创Mojo设计中(在一位非常聪明的家伙发现问题之前,已经有数百人讨论了b $ b b。)


另一方面,在普通编程中,概念模型非常简单

和足够。


想象一个右值作为整数值5,这就是你所需要的。


const int x = 5 * 125; // 5被消耗并被遗忘

const int y = 5; // 5过着漫长而重要的生活

int f(const int& n){
返回5 * n; // 5必须在某处的阴影中留下来
}

这是否意味着x和y仅在初始化(定义)后成为常量值?


是的。它们在初始化之前不存在。并且初始化是

没有赋值,尽管语法几乎相同。


初始化不被赋值的原因(在C ++中)是

初始化可能必须从原始内存构造一个对象,而

赋值必须更改现有对象,例如解除分配的东西。


但是说左值转换为右值对我来说并不重要。
在CPU中实际发生的事情是改变代表性
对象?


可能。在'a = b + 1;''的情况下,通过将& b的内容加载到处理器寄存器中,可以将左值''b''转换为
rvalue。例如。


另外,如果rvalue /是/对象,它有一个存储位置不是吗?


见上文。有可能。但是你不能直接取rvalue的地址,

并且你无法确定获得该地址,除非它是一个具有返回地址的

a函数的对象,特别是在内置

类型的情况下,它可能没有真正的存储位置,除非可能是嵌入在机器代码指令中的
,以及典型的优化

编译器,即使可能不存在; rvalue可能只存在于概念上,

这就是重点。


这里有一些我想念的东西。
程序如何表示和处理同一个对象作为右值或左值有什么不同?



Oops, that was not general enough. The function
std::string foo(){ return "Hey"; }
returns an rvalue because a temporary object is an rvalue. You cannot take
its address because conceptually it has no storage location. But in terms of
machine code it really has, in this particular case, and if you then define
void bar( std::string const& s ){ std::cout << &s << std::endl; }
and call it like
bar( foo() );
that location may be used directly, and if so then ''bar'' will display it
(also the object may itself have a function that gives its address).

No, one does not need to be stupid in order not to think of that.

The exact rules for this are _very_ complicated & hazy, e.g. causing a problem
in Andrei Alexandrescu''s original Mojo design (which was reviewed by hundreds
of people before one really smart fellow spotted the problem).

On the other hand in ordinary programming the conceptual model is very simple
and suffices.

Think of an rvalue as the integer value 5, and that''s all you need.

const int x = 5 * 125; // 5 is consumed and forgotten

const int y = 5; // 5 lives a long and significant life

int f(const int& n){
return 5 * n; // 5 has to stick around in the shadows somewhere
}

Does this mean that x and y only
become const lvalues after they are initialized (defined)?
Yes. They do not exist before their initializations. And initialization is
not assignment, in spite of having nearly the same syntax.

The reason for initialization not being assignment (in C++) is that
initialization may have to construct an object from raw memory, whereas
assignment must change an existing object, e.g. deallocate stuff.

But to say an lvalue is converted to an rvalue doesn''t mean much to me.
Does something actually happen in the CPU to change the representation of
the object?
It might. In the case of ''a = b + 1;'' the lvalue ''b'' may be converted to
rvalue by loading the contents of &b into a processor register. For example.

Also, if the rvalue /is/ an object, it has a storage location doesn''t it?
See above. It may. But you cannot directly take the address of an rvalue,
and you cannot for sure obtain that address unless it''s an object that has
a function that returns the address, and especially in the case of built-in
types it may not really have a storage location except in the sense of perhaps
being embedded in a machine code instruction, and for a typical optimizing
compiler even that may not exist; the rvalue might exist only conceptually,
which is much of the point.

There''s something I''m missing here. What is the difference in how the
program represents and process the same object as an rvalue or an lvalue?




区别在于程序文本是什么允许这样做。例如。你不能

改变价值5.你不能在价值上调用非常量函数。


-

A:因为它弄乱了人们通常阅读文本的顺序。

问:为什么顶级发布这么糟糕的事情?

A:热门发布。

问:usenet和电子邮件中最烦人的事情是什么?



The difference is in what the program text is allowed to do. E.g. you cannot
change the value 5. And you cannot call non-const functions on rvalues.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


这篇关于string literal是一个左值;其他文字是右值。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆