C++中operator<<调用顺序问题

来源:互联网 发布:discuz源码分析 编辑:程序博客网 时间:2024/06/05 20:30

今天发现一个奇怪的问题,有一个函数,该函数会记录原来的状态,调用一次以后,下次调用就会使用原来的结果,从而提高性能,假如函数是这样的
int GetValue(bool update=false);
如果update=true则更新其值,否则不更新.在测试时我这样输出其值:

cout<

期望两个值是相等的,可是输出结果却不相等,单步跟踪发现,该句先调用的面的函数GetValue(),而后调用前面的GetValue(true),前都用的是旧值,而后者用的是新值,所以其值不同,感觉很奇怪。

其实应该是cout<cout.operator<<(GetValue(true))
该表达式返回一个cout的引用,然后调用cout.operator<<(GetValue())所以,其显示的调用应该是
(cout.operator<<(GetValue(true))).operator<<(GetValue())
然而两次的运行结果却不一样,在VC9和Cygwin中的gcc 3.3.4都试的,结果一致。

然而,我又试了一下operator>>此时个编译器执行顺序即不一致了。

下面是测试程序:

#include
using namespace std;

int GetValue(bool update=false)
{
    static int val=0;
    if(update)
        val += 10;
    return val;
}

int main(int argc, char* argv[])
{
    char str[5];
    int i=0;
    str[4]=0;

    cout<<"Implicit call:/n";
    cout<<"GetValue(true)="<        <<"; GetValue(false)="<

    cout<<"Explicit call:/n";
    (cout.operator<<(GetValue(true))).operator<<(GetValue())<

    cout<<"Implicit int:/n";
    cout<

    i = 0;
    cout<<"Please input 4 letters"<    cin>>str[i++]>>str[i++]>>str[i++]>>str[i++];
    cout<}

VC9编译后的执行结果:

Implicit call:
GetValue(true)=10; GetValue(false)=0
Explicit call:
2010
Implicit int:
543210
Please input 4 letters
a b c d e // 输入
dcba

Cygwin中gcc 3.3.4编译后的执行结果:

Implicit call:
GetValue(true)=10; GetValue(false)=0
Explicit call:
2010
Implicit int:
012345
Please input 4 letters
a b c d   // 输入
abcd

而在C++的标准1998,2003版中的5.8 Shift operators也都明确说明了<< 和 >>是The shift operators << and >> group left-to-right. 而且我把优化选项已经关掉了,跟标准仍然不一致。显然这些编译器都没有按标准做。这编译器搞得“我很郁闷,很费解啊”!虽然operator<<的执行顺序两个编译器是一致的,但其它的编译器会不是又不一样呢?还没试呢,有时间再试试吧,即便是一致又有什么用呢?谁在写程序的时候倒着写啊?

结论:在operator<<和operator>>的表达式中要使用固定值,千万不要编写由于表达式中的子表达式执行顺序不一样,而可能造成运行结果不一样的情况,最保险的是根本就不要在这两个操作符构成的表达式中进行任何运算,如果想要使用运算,这两个表达式在每句中只出现一次,然后安排好句子的顺序,严格控制程序的执行结果。

原创粉丝点击