3

I'm new to c++ and I have recently spent a couple of days reading about pointers.I realized that the 2 following codes give me different results although they seem identical.

the first code:

int a = 5;
int* ptr = &a;
cout << ptr;
cout << "\n" << ++ptr;

the second code:

int a = 5;
int* ptr = &a;
cout << ptr << "\n" << ++ptr;

here is the output of the first one:

0043F940
0043F944

the output of the second one:

003AFE20
003AFE20

the first one seems more logical to me since it first outputs the address of a and then the address of the next integer location.But in the second one ptr is apparently always pointing to a.
Can someone explain this difference to me?
Thank you in advance.

  • 1
    The second code snippet has undefined behavior because the order of evaluation of function arguments is unspecified. – Vlad from Moscow Sep 10 '19 at 16:10
  • 1
    "*But in the second one ptr is apparently always pointing to a.*" How did you determine that? Isn't it much more likely that you've just output the incremented value twice? – David Schwartz Sep 10 '19 at 16:16
  • As @VladfromMoscow pointed out, the order is undefined. Thus, `++ptr` gets evaluated first and then `ptr` again, with the same value. They likely don't point to `a`, but to the next location. You could verify this with `cout << &a` – Mirko Sep 10 '19 at 16:18
  • @VladfromMoscow: No longer in C++17 (which OP doesn't use), see https://en.cppreference.com/w/cpp/language/eval_order – Jarod42 Sep 10 '19 at 16:32
  • Reopened. The alleged duplicate had nothing to do with this question. – Pete Becker Sep 10 '19 at 20:12
  • Thank you guys for all your comments and answers. I didn't notice that it was related to evaluation sequence and that was why I couldn't find any answer over the web and i thought that might be a visual studio bug.Thanks for taking your time to answer and sorry it was somehow duplicate :) – Mohammad Parvari Sep 11 '19 at 16:34

2 Answers2

2

Look closely at: cout << ptr << "\n" << ++ptr;

Your code is like f (ptr, ++ptr); which has the same issue.

Both lines of code have two places where the value of ptr is read and one place where the value of ptr is written. While the read in ++ptr has to take place before the write, the read of ptr (for << ptr or the first parameter to f) has no restrictions on when it takes place and can take place either before or after the write.

This is because C++ does not specify the order in which a function's parameters are evaluated. Apparently, on your platform, with your compiler flags, the increment happens to take place before the other read. So you output the incremented value twice.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

Let us name the operator<<(a, b) now as function f(a, b). Using this notation cout << 5 becomes f(cout, 5). Using the fact that the << operator has left-to-right associativity, cout << 4 << "a" becomes f(f(cout, 4), "a").

Let's translate your code:

cout << ptr << "\n" << ++ptr;

to:

f(f(f(cout, ptr), "\n"), ++ptr);

As you can see, the most outer call to f has as second argument ++ptr. Since C++ doesn't specify the order of evaluation of arguments to a function call, it is free to increment ptr first, before evaluating the nested f(...) function call.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287