您的位置:首页 > 其它

小议 cout << i << " " << i++ << endl

2009-08-06 09:39 459 查看
前注: 本文除了最后半句话在讨论“i++”的问题外,通篇都不关i++或++i什么事。千万别望文生义。

 

王富涛 的一个话题,问:

Code:

int i = 0;  

cout << i << " " << i++ << endl;  

为什么在VC6里,DEBUG 版本输出 1,0 ,而Release版本输出0,0

通常编译器,都是编译Release程序时,容易出错,因为错误的优化。不过VC的习惯是,通常RELEASE版运行的结果,更接近C++标准,私下里我们称它的优化,就是让程序更“标准化”。

这边不准备纠缠这个问题。倒是来看看,cout << i << " " << i++ << endl 是些什么东东?其它上面的代码相当于:

Code:

int i=0;  

::operator << (cout.operator << (i), " ").operator << (i++).operator << (endl);  

为什么这么复杂?是因为凑巧中间夹着输出了一个字符串,此时调用的是自由函数 ::operator(ostream&, char const *);

还是有些眼晕,那么我们再简化一下:

Code:

#define OUT operator<<  

::OUT(cout.OUT(i), " ").OUT(i++).OUT(endl);  

#undef OUT  

为了描述方便,干脆为每个OUT编个号码:

Code:

::OUT_1(cout.OUT_2(i), " ").OUT_3(i++).OUT_4(endl);    

其中,OUT_1 是一个全局自由函数,它带两个参数,一个是流,另一个是字符串,大致原型可以写成:

Code:

ostream& OUT_1(ostream& os, char const * pstr);  

而 OUT_2 ~ OUT_4, 都是同一个函数,它们是某个类的成员函数。

cout 就是那个类的一个对象(换句话说:cout一个变量)。

endl 本是一个函数 endl()……但这里用的是它的地址,这是另一个话题了。

忽略与本问题无关的,最终代码结构类似:

Code:

foo_1( o.foo_2(i), " ").foo_3(i++).foo_4(endl);  

foo_1() 函数运行之后,返回一个对象,假设为a。接着,调用a的成员函数foo_3,拆解代码为:

Code:

a = foo_1 (...);  

a.foo_3 (i++);  

//...  

但要执行foo_1,则必须求出它的第一个入参的值,所以再拆解:

Code:

a_0 = o.foo_2(i);  

a_1 = foo_1(a_0, " ");  

a_2 = a_1.foo_3(i++);  

a_3 = a_2.foo_4(endl);  

补充一句,a_x 在本例中,其实都是同一个对象。

不管如何,在执行 a_0 = o.foo_2(i)时,关后面的 a_1.foo_3(i++)什么事呢?那时候 foo_3()的宿主a_1还没有产生呢,如果有编译器非在这时让i++影响了前面的o.foo_2(i)的执行,造成后者输出一个“1”来,那能说明什么呢?我想,只能说是它错了吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编译器 优化 c