Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post-increment vs Assignment in C++ operation precedence table

I stumbled upon https://en.cppreference.com/w/cpp/language/operator_precedence

On the chart, I see that post-increment operator (++) is way above assignment operator (=).

enter image description here

However, I know that

int a[] = {10,20};
int* b = &a[0];

*(b++) = 5;

cout << a[0] << endl; // 5
cout << a[1] << endl; // 20
cout << *b << endl; // 20, now points to a[1]

I always take it for grant that post-increment happens after the assignment operator. However, if I follow the operation precedence chart, then isn't post-increment suppose to happen before = operation? Isn't the answer suppose to be a={10, 5} rather than a={5, 20}?

like image 641
pbeta Avatar asked Oct 19 '25 06:10

pbeta


2 Answers

"Precedence" is misleading. It has little to do in general with evaluation order (what happens first), but instead determines what is the operand of each operator for the purpose of evaluation. But let's examine your example.

*(b++) = 5;

This means that 5 is to be assigned to the lvalue on the left. And since C++17, we know that 5 is evaluated entirely before *(b++). Prior to that, they could be evaluated in any order.

Now, b++ has the meaning of "increment b, but evaluate to its previous value". So b++ may cause the increment to happen prior to the assignment taking place, yes, but the value of (b++) is the address before the increment happened. And that is why b is updated to point at the next element, while modifying the current one, in one expression.

like image 81
StoryTeller - Unslander Monica Avatar answered Oct 21 '25 08:10

StoryTeller - Unslander Monica


Post increment (b++) increments b, then returns the previous value of b.

Pre increment (++b) increments b, then returns the new value of b.

To get the behavior you're expecting, change from post-increment to pre-increment.

For example:

#include <iostream>

int main() {
  int a[] = {10, 20};
  int *b = &a[0];

  *(++b) = 5;

  std::cout << a[0] << std::endl;
  std::cout << a[1] << std::endl;
  std::cout << *b << std::endl;
}

Yields the following output:

10
5
5
like image 41
druckermanly Avatar answered Oct 21 '25 08:10

druckermanly