tags:

views:

89

answers:

3

Hi...

The associativity of stream insertion operator is rtl, forgetting this fact sometimes cause to runtime or logical errors. for example:

1st-

int F()
{
   static int internal_counter c=0;
   return ++c;
}

in the main function:

//....here is main()
cout<<”1st=”<<F()<<”,2nd=”<<F()<<”,3rd=”<<F();

and the output is:

1st=3,2nd=2,3rd=1

that is different from what we expect at first look.

2nd- suppose that we have an implementation of stack data structure like this:

    //
    //... a Stack<DataType> class …… 
    //

    Stack<int> st(10);
    for(int i=1;i<11;i++)
       st.push(i);

cout<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl;

expected output is something like:

10
9
8
7

but we have:

7
8
9
10

There is no internal bug of << implementation but it can be so confusing... and finally[:-)] my question: is there any way to change associativity of an operator by overloading it?

do you think this could be not reverse? i mean is it possible to change order by modifying or changing an open source STL?

+8  A: 

No there isn't. But I think you may be mixing up associativity with evaluation order. The only operators that specify an evalualtion order are &&, || and , (comma). When you say:

cout<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl<<st.pop()<<endl;

the compiler can evaluate sub-expressions such as st.pop() in any order it likes, which is what causes the unexpected output.

anon
+5  A: 

The only things that are right-associative are the assignment operators. See §5.4 to 5.18 of the standard. The << operators are evaluated left-to-right or the messages would be backward in grammar, not in content. The content is due to side effects, which are unordered in C++ except (as Neil mentions) for "short-circuit" && and ||, and comma.

Potatoswatter
@Sorush: it's ok, you can accept Neil's answer if you want…
Potatoswatter
A: 

To see how this is an order of evaluation issue and not an associativity issue, modify your code to this:

int a = st.pop();
int b = st.pop();
int c = st.pop();
cout << a << endl << b << endl << c << endl;
R Samuel Klatchko