- 论坛徽章:
- 0
|
首先非常感谢whyglinux兄的大力支持和不遗余力的指导。
在标准中也没有“一般的lvalue”一说。不理解你说的“一般的lvalue”指的是什么:是"modifiable lvalue"还是非"modifiable lvalue"?抑或是同时指两者?
我查找到的原文这样说的:
regular "lvalue" and "modifiable lvalue"
(当然这里不是说"regular lvalue"和"modifiable lvalue",因为没有"regular lvalue"这一术语。是在下直译过来的)
可能这样说比较好一点吧:"lvalue"中包含一类特殊的"lvalue"——"modifiable lvalue"。我觉得理解起来也可以像您那样说:
"modifiable lvalue"和非"modifiable lvalue" 0x800000FF是整型,不是指针类型,因此 *0x800000FF 是非法的,还谈不上是左值还是右值的问题。
你可能是想说明 *(void*)0x800000FF,不过显然也是非法的。
另外,你说的“cast operator可以产生"lvalue"”是错误的。恰恰相反,在标准 C 和 C++ 中,cast operator 操作结果产生的是右值。
谢谢斧正,这个例子用来说明some operators can yield lvalue是错误的,这是其一;另一方面,说cast operator 产生"lvalue"是错误的,它产生左值是编译器(如GCC)的extentions,标准C中在脚注中明确指出:
"A cast does not yield an lvalue."
(因为标准中的脚注并不是标准的正式文本,才导致有的编译器另行对待吧)
呵呵还是想举个例子,比如说indirection operator产生"lvalue"(这里的产生并非指从"lvalue"到"lvalue"),这个例子不知道对不对,请不吝赐教:
- #include <stdlib.h>
- #include <stdio.h>
- char *mystrcp(char *dest, const char *src)
- {
- char *temp;
- temp = dest;
- while ((*dest++ = *src++) != '\0')
- ;
-
- return dest;
- }
- int main(int argc, char *argv[])
- {
- char *dest = malloc(100 * sizeof (*dest));
- char *src = "Hello World";
-
- *mystrcp(dest, src) = 'I'; /********************/
- printf("dest: %s\n", dest);
-
- system("pause");
- return 0;
- }
复制代码
这段代码在DEV-CPP4.9.9.2和VC++6.0下试验未出现任何问题。首先函数调用肯定不是"lvalue",这里的*operator将产生一个"lvalue"。
>> 那么是否可以这样理解:
>> "lvalue"必须对应于一块存储空间,并且是对非void 类型的object的reference。
注意标准中说的是“An l-value is an expression with an object type or an incomplete type other than void”。因此,强调的是非 void 的 object type 或 incomplete type,而不是实际存在的 object。我在前面已经说过,左值概念与对象(存储空间)的实际存在与否无关。当然了,if an lvalue does not designate an object when it is evaluated, the behavior is undefined。
您说得很对,但这里我并未说object必须是实际存在的object啊。不过你这一段,更能加深大家的理解。还是很感谢。
>> "rvalue"可以理解为一段存储空间表示的值或一个表达式的值,它强调的是value的本意。
“一段存储空间表示的值”其实就是“对象的值”。获得对象的值的过程我们通常称之为“求值”。对对象求值是一个由左值转化为右值的过程(lvalue-to-rvalue),所以对象的值是右值,但不能说对象是右值。关于 lvalue-to-rvalue 转化在 C99 标准的 6.3.2.1-2 和 -3 一节中叙述。
嗯,这里我觉得可能啰嗦了一点但是并没有歧义,“一段内存空间表示的值”最终还是“值”的意思。好谢谢指明转化的位置。
一个单独的对象也可以作为表达式使用,所以上述这句话可简写为“"rvalue"可以理解为表达式的值”。这也是标准中出现的描述。
对,标准在脚注中说的原文是:
What is sometimes called "rvalue" is in this International Standard described as the "value of an expression".
以上那样说只是我自己的理解:“一段存储空间表示的值”是我想强调一类由"lvalue" 转化来的"rvalue"吧。
>> "lvalue"可以作为"rvalue",但不是所有的都可以。
lvalue-to-rvalue 转化是标准规定的。lvalue 转换为 rvalue 实际上就是对左值求值的过程。存在不能对其求值的左值吗?
你在上面举的例子也说明不了你这句话的正确性。因为在 C 中,所有的函数调用产生的都是右值,而不是你说的左值(在 C++ 中,除了返回引用的函数调用是左值外,其它的函数调用结果也都是右值)。
嗯,首先承认错误,任何函数调用不是"lvalue",还有标准也明确给出函数名(function designator)不是左值,因为function designator 是function type而不是object type,所以它也不是"lvalue"。但有一点是:不是"lvalue"就是"rvalue"吗?
那么这个例子中:
- void foo(void)
- {
- /*do something...*/
- }
- int i;
- i = foo(); /*function call是表达式,函数调用foo()不是"lvalue"但在这里也不能作为"rvalue"*/
复制代码 |
|