3

Execution of this simple code:

int  foo(int* a){
    cout <<"a="<<a;
    *a=1;
    cout <<", *a="<<*a<<endl;
    return 0;}

int main () {
    int* ptr;
    ptr=new int[2];
    ptr[0]=0;
    ptr[1]=0;

    cout<< foo(ptr) <<" "<< ptr <<" *ptr="<< *ptr <<endl;
    cout<< foo(ptr) <<" "<< ptr <<" *ptr="<< *ptr <<endl;

    return 0;}

Leads to (linux):

a=0x939f008, *a=1
0 0x939f008 *ptr=0
a=0x939f008, *a=1
0 0x939f008 *ptr=1

Please explain why *ptr=0 in the second line, but not in the fourth; could it be, that "things" are "fetched" to cout from right to left? Than - how does it really work (step-by-step at runtime)?

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
P Marecki
  • 1,108
  • 15
  • 19
  • Things to try: 1) What happens if you call `foo` before you print? 2) what happens if you print `*ptr` first followed by `foo(ptr)`? 3) What happens when you print `a[0]` and `a[1]` after the original `cout`? – Dennis Feb 27 '12 at 08:23
  • @Dennis (1) *ptr gets changed, so "1" will be printed in subsequent cout's, (2) this is interesting: cout<<*ptr<<" II "< – P Marecki Feb 27 '12 at 08:42

1 Answers1

5

The order of evaluation of arguments to a function is Unspecified as per the C++ Standard.
It may be:

  • Left to Right or
  • Right to Left or
  • Any other order

One of my previous answer here, explains this in depth and detail.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 1
    Also, I wouldn't recommend calling cout in a function called from a call to cout. It makes for a terribly frustrating debugging experience. – Mr Lister Feb 27 '12 at 08:29
  • It's not all bad. C++ _does_ guarantee that all arguments to a function are evaluated before the function is called. Every `<<` is an independent function call, which is why `cout` printing is guaranteed to work left-to-right. – MSalters Feb 27 '12 at 10:16
  • @Msalters The **printing** is guaranteed to be left to right, but the **evaluation** of arguments is not. [Here](http://ideone.com/H0g3E) is some evidence. As you probably know, the expression `std::cout << foo() << bar()` is just syntactic sugar for `operator<<(operator<<(std::cout, foo()), bar())`, and the implementation is free to evaluate the arguments `foo()` and `bar()` in any order. – fredoverflow Feb 27 '12 at 10:28
  • @FredOverflow: That's entirely true, but I'm explaining _why_ the printing is guaranteed left-to-right: it's not a single "cout call", but multiple calls of `<<`. (The question asked for a step-by-step explanation) – MSalters Feb 27 '12 at 10:33
  • @MSalters: hum... actually, no. In the case exposed by Fred, `bar()` can perfectly be called before `foo()` so if both `bar` and `foo` print, it will produce a somewhat surprising result. – Matthieu M. Feb 27 '12 at 11:24