C++ iso2003,标准党进来一观

qscool1987 2013-11-21 09:30:45

#include "stdafx.h"
class A
{
public:
//A():a(0){}

int a;
int f()
{return a;}
};
A fun()
{
return A();
}
int _tmain(int argc, _TCHAR* argv[])
{
fun().a = 5 ;
return 0;
}
//不注释掉构造函数,编译不过

WHY?
两段程序对于fun().a的计算是怎么回事?一次计算成左值,一次计算成右值,有谁懂不?
...全文
500 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
JiMoKuangXiangQu 2013-11-26
  • 打赏
  • 举报
回复
进坑里看一下,然后赶紧出去了
Adol1111 2013-11-26
  • 打赏
  • 举报
回复
C/C++的左值右值有时候还是烦的,特别是编译器本身有问题的时候,更影响正常的学习、使用。
qscool1987 2013-11-22
  • 打赏
  • 举报
回复
引用 13 楼 supermegaboy 的回复:
[quote=引用 12 楼 qscool1987 的回复:] 别怪我挖坑,也别搪塞说我编译器坑,如果真是编译器坑,请举个把例子让大家以后注意下 对于第一个问题,我也觉得是编译器坑 第二个问题: *(fun().a) = m;//这句是我的解释不正确? [quote=引用 4 楼 supermegaboy 的回复:] 是编译器出现了非标准行为。fun().a一定是右值。 此外,以后请不要叫什么“标准党”,阅读语言标准是C/C++程序员的基本能力,不是“另一群人”。
我也是根据这位如此肯定的回复所做的推断。 希望得到让人信服的回答。[/quote] 你第二个问题的解释不正确,间接运算符的结果是左值。 对于第一个问题,C++03漏写了当对象表达式是右值时整个后缀表达式的左值性,这个问题在C++11已经修复过来了。详情可参考:http://blog.csdn.net/code_crash/article/details/7038329[/quote] 首先感谢你提供的资料,既然C++11修正了这个问题,那么第二个问题也就不是问题。 拜读过你的博客之后对其中的这句话持怀疑态度 C和C++标准都规定如果E1为左值,则E1.E2也是左值 E1.E2的结果,还得由E2来决定,如果E2是右值,那么E1.E2是右值,如果是E2是左值,则E1.E2是左值,这是我的理解
飞天御剑流 2013-11-22
  • 打赏
  • 举报
回复
引用 12 楼 qscool1987 的回复:
别怪我挖坑,也别搪塞说我编译器坑,如果真是编译器坑,请举个把例子让大家以后注意下 对于第一个问题,我也觉得是编译器坑 第二个问题: *(fun().a) = m;//这句是我的解释不正确? [quote=引用 4 楼 supermegaboy 的回复:] 是编译器出现了非标准行为。fun().a一定是右值。 此外,以后请不要叫什么“标准党”,阅读语言标准是C/C++程序员的基本能力,不是“另一群人”。
我也是根据这位如此肯定的回复所做的推断。 希望得到让人信服的回答。[/quote] 你第二个问题的解释不正确,间接运算符的结果是左值。 对于第一个问题,C++03漏写了当对象表达式是右值时整个后缀表达式的左值性,这个问题在C++11已经修复过来了。详情可参考:http://blog.csdn.net/code_crash/article/details/7038329
qscool1987 2013-11-22
  • 打赏
  • 举报
回复
别怪我挖坑,也别搪塞说我编译器坑,如果真是编译器坑,请举个把例子让大家以后注意下 对于第一个问题,我也觉得是编译器坑 第二个问题: *(fun().a) = m;//这句是我的解释不正确?
引用 4 楼 supermegaboy 的回复:
是编译器出现了非标准行为。fun().a一定是右值。 此外,以后请不要叫什么“标准党”,阅读语言标准是C/C++程序员的基本能力,不是“另一群人”。
我也是根据这位如此肯定的回复所做的推断。 希望得到让人信服的回答。
qscool1987 2013-11-22
  • 打赏
  • 举报
回复

#include "stdafx.h"
class A
{
	public:
	//A():a(0){}

	int b;
	int *a;
	int& f()
	{return *a;}
	int ff()
	{return b;}
	
	int& operator[](int index)
	{return arr[index];}
private:
	int arr[100];
};
class B
{
public:
	//B():b(0){}
	int b;
};

B fff()
{return B();}

A fun()
{
	return A();
}
A* fun1()
{
	return new A;
}
A fun2()
{
	return A();
}
// .操作表达式的结果是由左操作数和右操作数共同决定,先计算左操作数,然后共同决定整个表达式的结果
// 那是不是可以这么理解:
// 左操作数为左值,那么整个表达式的结果可能为左值也可能为右值,这个时候 看.操作右表达式的结果是左值还是右值来定。
// 如果 . 操作的左操作数为右值,那整个表达式一定为右值。 
int _tmain(int argc, _TCHAR* argv[])
{
	int m = 5;			//
	*(fun().a) = m;		//右值.左值      结果为左值  如果按上述解释,这句代码是不符合标准的  
	//fun().b = m;          //右值.左值      结果为右值  符合解释 
	fun1()->b = m;          //左值.左值      结果为左值  符合解释
	//fun2().ff() = 5;	//右值.右值		不能编译    符合解释
	(*fun1())[12] = 3;	//左值[常量表达式]           符合解释
	(new A)->b = m;		//左值->左值     结果为左值  符合解释
	//(new A)->ff() = m;    //左值->右值     不能编译    符合解释
	fff().b = 5;		//右值.左值      结果为左值  如果按上述解释,这句代码是不符合标准的
	return 0;
}
//如果上述解释不正确,请问,该如何解释
//*(fun().a) = m;
//fff().b = 5;
qscool1987 2013-11-22
  • 打赏
  • 举报
回复
引用 4 楼 supermegaboy 的回复:
是编译器出现了非标准行为。fun().a一定是右值。 此外,以后请不要叫什么“标准党”,阅读语言标准是C/C++程序员的基本能力,不是“另一群人”。
.操作表达式的结果是由左操作数和右操作数共同决定,是不是说, 那是不是可以这么理解: 左操作数为左值,那么整个表达式的结果可能为左值也可能为右值,这个时候 看.操作右表达式的结果是左值还是右值来定。 如果.操作的左操作数为右值,那整个表达式一定为右值。
dyw 2013-11-22
  • 打赏
  • 举报
回复
有点意思。哪一个版本的编译器? 纵使能赋值,值也取不出来了。
听风看云 2013-11-22
  • 打赏
  • 举报
回复
真心觉得C++的标准够猥琐
ri_aje 2013-11-22
  • 打赏
  • 举报
回复
编译器 bug,以后遇到这种问题,可以多试几个编译器,比如 g++。
JPF1024 2013-11-22
  • 打赏
  • 举报
回复
引用 16 楼 unituniverse2 的回复:
多换几个编译器试试 vs2010~2013的词法解析器真的很毛糙,很多该做的检测都没有做 gcc的结果:
C:\Documents and Settings\Rabbits' World\Desktop\test.cpp:16:8: error: using tem
porary as lvalue [-fpermissive]
  A().a = 0;
        ^
学习。
漫步者、 2013-11-22
  • 打赏
  • 举报
回复
,研究语法,蛋疼
unituniverse2 2013-11-22
  • 打赏
  • 举报
回复
现在的左右值的定义和操作数放左还是右没有直接的关系。而是看是否是非具名临时对象
unituniverse2 2013-11-22
  • 打赏
  • 举报
回复
多换几个编译器试试 vs2010~2013的词法解析器真的很毛糙,很多该做的检测都没有做 gcc的结果:
C:\Documents and Settings\Rabbits' World\Desktop\test.cpp:16:8: error: using tem
porary as lvalue [-fpermissive]
  A().a = 0;
        ^
飞天御剑流 2013-11-22
  • 打赏
  • 举报
回复
引用 14 楼 qscool1987 的回复:
[quote=引用 13 楼 supermegaboy 的回复:] [quote=引用 12 楼 qscool1987 的回复:] 别怪我挖坑,也别搪塞说我编译器坑,如果真是编译器坑,请举个把例子让大家以后注意下 对于第一个问题,我也觉得是编译器坑 第二个问题: *(fun().a) = m;//这句是我的解释不正确? [quote=引用 4 楼 supermegaboy 的回复:] 是编译器出现了非标准行为。fun().a一定是右值。 此外,以后请不要叫什么“标准党”,阅读语言标准是C/C++程序员的基本能力,不是“另一群人”。
我也是根据这位如此肯定的回复所做的推断。 希望得到让人信服的回答。[/quote] 你第二个问题的解释不正确,间接运算符的结果是左值。 对于第一个问题,C++03漏写了当对象表达式是右值时整个后缀表达式的左值性,这个问题在C++11已经修复过来了。详情可参考:http://blog.csdn.net/code_crash/article/details/7038329[/quote] 首先感谢你提供的资料,既然C++11修正了这个问题,那么第二个问题也就不是问题。 拜读过你的博客之后对其中的这句话持怀疑态度 C和C++标准都规定如果E1为左值,则E1.E2也是左值 E1.E2的结果,还得由E2来决定,如果E2是右值,那么E1.E2是右值,如果是E2是左值,则E1.E2是左值,这是我的理解 [/quote] 对于非静态非引用成员,当E1是左值时,E2不可能是右值的。 C++03: 5.2.5 Class member access If E2 is a non-static data member, and the type of E1 is “cq1 vq1 X”, and the type of E2 is “cq2 vq2 T”, the expression designates the named member of the object designated by the first expression. If E1 is an lvalue, then E1.E2 is an lvalue. C++11: 5.2.5 Class member access If E2 is a non-static data member and the type of E1 is “cq1 vq1 X”, and the type of E2 is “cq2 vq2 T”, the expression designates the named member of the object designated by the first expression. If E1 is an lvalue, then E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue; otherwise, it is a prvalue. C++11已经补上了E1为xvalue及prvalue的情况,C++03漏了。
  • 打赏
  • 举报
回复
Todd_Pointer 2013-11-21
  • 打赏
  • 举报
回复
非标准党感觉不可思议
zxx178239 2013-11-21
  • 打赏
  • 举报
回复
围观一下
飞天御剑流 2013-11-21
  • 打赏
  • 举报
回复
是编译器出现了非标准行为。fun().a一定是右值。 此外,以后请不要叫什么“标准党”,阅读语言标准是C/C++程序员的基本能力,不是“另一群人”。
iamnobody 2013-11-21
  • 打赏
  • 举报
回复
VS坑,跟标准没关系
加载更多回复(2)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧