4
#include <iostream>
#include <string>

using namespace std;

int main()
{
  int a = 5;
  int& b = a;
  int* c = &a;

  cout << "CASE 1" << endl;
  cout << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
  b = 10;
  cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl << endl;

  cout << "CASE 2";
  a = 5;
  cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
  b = 10;
  cout << endl << "a is " << a << endl << "b is " << ++b << endl << "c is " << *c << endl << endl;

  cout << "CASE 3";
  a = 5;
  cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
  b = 10;
  cout << endl << "a is " << a << endl << "b is " << b++ << endl << "c is " << *c << endl;
}

The output:

CASE 1:

a is 5. b is 5. c is 5.
a is 10. b is 10. c is 10.

CASE 2:

a is 5. b is 5. c is 5.

a is 11. b is 11. c is 10.

CASE 3:

a is 5. b is 5. c is 5.
a is 11. b is 10. c is 10.

I understand CASE 1. But I am having difficulty understanding CASE 2 and CASE 3. Can someone explain why doesn't c get updated with new value in both cases?

cbuchart
  • 10,847
  • 9
  • 53
  • 93
nSv23
  • 429
  • 6
  • 19
  • Can you add the output – Mike May 07 '17 at 14:25
  • It is undefined as to the order of operations of `<<`. Simply put, `operator <<` is a function, and those are its arguments. Arguments to a function can be evaluated in any order, as it is implementation defined. – PaulMcKenzie May 07 '17 at 14:44
  • Looks like undefined and/or unspecified behaviour. Perhaps even depending on which standard version of C++ is being used. The rules for sequencing and operator precedence are almost hopelessly complicated, see http://en.cppreference.com/w/cpp/language/eval_order and http://en.cppreference.com/w/cpp/language/operator_precedence. My personal rule to stay clear from all that trouble is to never access an object to which `++` is applied in the same expression. – Christian Hackl May 07 '17 at 14:47

2 Answers2

5

The evaluation order of operands is unspecified, and you're modifying an object and reading it without those operations being sequenced.

Thus, your program is as undefined as cout << a << a++;, and anything can happen.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • 3
    This is a bit vague. "Anything can happen" makes it look like it has Undefined Behavior, but it's only true if using old C++ (before C++11). "As undefined as ..." is correct but not helpful; I believe it's actually "UB in C++03; unspecified in C++11 and later" for both code in OP and `cout << a << a++`. I am not sure though. – anatolyg May 07 '17 at 14:51
  • 3
    @anatolyg Operand evaluations are unsequenced in C++11 (§1.9, item 15), leading to undefined behaviour. I believe 17 changes this. – molbdnilo May 07 '17 at 14:57
1

I think your problem is due to what is called sequence points. You can have a long read about that in this answer but in a few words it basically states the order or evaluation of the elements of an expression.

Update in your case this order is undefined, although some compilers seem to make it right-to-left.

Community
  • 1
  • 1
cbuchart
  • 10,847
  • 9
  • 53
  • 93