0

I'm trying to understand how the parentheses affects the precedence in an expression:

int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
auto b = arr;
std::cout << *(++b) << std::endl;

// output : 1

In this code I get the expected output but if I change it to:

std::cout << *(b++) << std::endl;
// output 0 

I get 0 as output. Because of the parentheses I though b++ will be evaluated first and then de-referencing will occur. It seems I was wrong, then I removed the parentheses completely and test with *++b and *b++ and get the same results.Does that mean the parentheses don't affect the precedence on this kind of expressions ? And why are the results of this two expressions are equivelant:

*(b + 1) 
*(++b) 

But it's not the case with *(b++) ?

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • 6
    Because that's pretty much the *definition* of postfix increment? Please explain what you think it should do and how that differs from prefix increment (`++b`). –  Sep 25 '14 at 10:39
  • tl;dr `b++ == b`, the parentheses do not magically change the result of the evaluation. – user657267 Sep 25 '14 at 10:41
  • @delnan yeah I'm aware of the difference but that is the parentheses I'm concerning about. – Selman Genç Sep 25 '14 at 10:43

3 Answers3

7

It does evaluate the b++ first. b++ increments b and returns the previous value of b, before the increment happened. The result of b++ and the value of b afterwards are different. Think of it as (using int instead of int * because a reference-to-pointer makes the signature ugly):

int postfix_increment(int &x) {
    int result = x;
    x = x + 1;
    return result;
}

(Except that using the incremented value before the next sequence point is undefined behavior.)

If you introduce a temporary variable for the result of the parenthesis, to make sure it's evaluated first, it may be easier to see the difference:

int *tmp = b++;
// At this point, b == tmp + 1!
std::cout << *tmp << std::endl;
Community
  • 1
  • 1
  • okey it makes it clear. btw I guess you are missing a `*` in tmp – Selman Genç Sep 25 '14 at 10:50
  • @Selman22 Yeah, missed that `b` is a pointer, not an int. Luckily is makes absolutely no difference for the explanation. –  Sep 25 '14 at 10:51
1

*(b++) is equivalent to storing the old pointer, incrementing the pointer and dereferencing the old pointer

int* post_increment(int* b) 
{
   int* old = b;
   ++b;
   return old;
}

It is an instructive exercise to write a thin iterator wrapper around a plain pointer. When writing user-defined iterators, the above post_increment() function is usually written an overloaded operator++(int). The int argument is purely to distinguish it from the pre-increment operator operator++(). In addition, you'd need an overloaded operator*() to dereference an iterator.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
0

*(b+1) works because you do math. Math takes parentheses into account. Only after Math is done, the expression gets evaluated.

*(++b) works because you increment before evaluation (prefix increment).

*(b++) doesn't work because you increment after evaluation (postfix increment).

Nimelrian
  • 1,726
  • 13
  • 23