返回信息流编译器直接把你那一坨运算符按右到左的语法顺序展开了~拆解完后编译出的东西如下:
call sub_4013EB ; 压栈调用hello2(),这里调用完就已经完成了"hello2"的输出
mov ebx, eax ; 函数返回值放入ebx
call sub_4013B9 ; 压栈调用hello1(),这里调用完就已经完成了"hello1"的输出
mov esi, eax ; 函数返回值放入esi
; 后边一大坨才是完成main中的输出
mov [esp+30h+var_2C], offset aA ; "a="
mov [esp+30h+var_30], offset dword_477860
call sub_4693B8
mov [esp+30h+var_30], esi ; 跟在"a="后边压入栈的是hello1的返回值
mov ecx, eax
call sub_449CDC ; call I/O
sub esp, 4
mov [esp+34h+var_30], offset aB ; " b="
mov [esp+34h+var_34], eax
call sub_4693B8
mov [esp+34h+var_34], ebx ; 跟在"b="后边压入栈的是hello2的返回值
mov ecx, eax
call sub_449CDC ; call I/O
看完这段能否理解了?
【 在 lcb 的大作中提到: 】
: #include <iostream>
: using namespace std;
: int hello1();
: ...................
这是一条镜像帖。来源:北邮人论坛 / cpp / #71636同步于 2013/6/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
Re: 求大神指点cout本质
tonyjansan
2013/6/7镜像同步6 回复
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
继续打屁屁。不是你想象的那样“从右往左”读。不可能的。
实际上发生的事是,程序要计算表达式 cout<<"a="<<hello1()<<" b="<<hello2()<<endl 的值。
也可以多加几个括号写成这样:
((((cout<<"a=")<<(hello1()))<<" b=")<<(hello2()))<<endl
也就是一个由5个“向左移位”(<<)运算符,两个函数调用表达式hello1()和hello2(),以及4个常量表达式cout, "a=", " b="和endl,组成的表达式。
C++对于表达式内各个部分的求值顺序没有规定。这里:
- 可以先求(cout<<"a=")的值(效果是输出a=),
- 也可以先求(hello1())的值(效果是输出hello1然后返回1),
- 也可以先求(hello2())的值(效果是输出hello2然后返回2)。
你无法确定你写出的程序实际上会先去求哪个值,因为C++的设计者也不知道。
所以,你看到的先输出hello2再输出hello1然后输出a=1 b=2,纯属意外,没有道理。
如果你真的关心先输出哪个,后输出哪个,你的程序不应该这样写。
比如,如果你希望先输出hello1,再输出hello2,再输出a=1 b=2,你应该这样写:
int a = hello1();
int b = hello2();
cout<<"a="<<a<<" b="<<b<<endl;
嗯。这就是纯属意外的那个“意外”。C++反正没有规定要按这个顺序求值,所以编译成这个样子纯属意外。当然,看看汇编总能看得清楚一些。
【 在 tonyjansan 的大作中提到: 】
: 编译器直接把你那一坨运算符按右到左的语法顺序展开了~拆解完后编译出的东西如下:
: call sub_4013EB ; 压栈调用hello2(),这里调用完就已经完成了"hello2"的输出
: mov ebx, eax ; 函数返回值放入ebx
: ...................
p.s. 你对运算符重载的理解是正确的。括号也正如你的方法加。顺序也是正确的。但关键不是这几个<<运算符执行的顺序(显然a<<b<<c<<d<<e肯定要先<<b再<<c再<<d再<<e),而是中间嵌套的两个“函数调用表达式”,也就是hello1()和hello2(),以及第一个<<运算符谁先执行谁后执行的问题。
【 在 lcb 的大作中提到: 】
: #include <iostream>
: using namespace std;
: int hello1();
: ...................
提醒lz一下,c++语言对于这个没有明确的定义,你用不同的编译器,甚至同一系列编译器的不同版本都有可能产生不一样的输出哦!试试就知道了!
【 在 lcb 的大作中提到: 】
: #include <iostream>
: using namespace std;
: int hello1();
: ...................
接着再请教吧。
3个问题:
1,i++!=j++;中有关i++,j++谁先执行的问题。我了解到的是,没有明确的规定。这样的写法应当避免
2,一个语句中有多个i++语句时,i的值被加上是在什么时候执行的。初步的结果是在语句结束后才执行。似乎也没有规定,可能不能编译器不一样
3,max(max(a,b),max(c,d))这样的语句,我想确定的是,一个函数要执行,肯定先要定的参数。也就是说第一个max要执行,要先执行后两个max,这个压栈过程是怎样的?多个函数参数时执行顺序应该也是没有规定的吧?
求大神指点,先谢谢啦。