Tarun Bhargava
Tarun Bhargava

Reputation: 49

Behaviour of preincrement operator

Consider the following code:

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char **argv) {
  vector<int> v = { 1 };
  auto it = v.begin();
  cout << ++(*it) << " " << v[0] << " " << endl;
  cout << v[0] << endl;
  return EXIT_SUCCESS;
}

When compiled and run, this code yields the following console output:

2 1 
2

Given that ++(*it) increments the first vector value, I would instead expect the following output:

2 2 
2

Why isn't the increment reflected in the first cout statement for v[0]?

Upvotes: 0

Views: 47

Answers (2)

melak47
melak47

Reputation: 4850

++(*it) will increment and return the element it refers to, not the iterator itself, so v[0] is 2 after evaluating that expression.

So why doesn't it print 222? Because the chain of operator<<s is actually nested function call, somewhat like this:

operator<<(operator<<(operator<<(operator<<(std::cout, ++(*it)), " "), v[0]), " ");

and the bit of interest:

operator<<(operator<<(std::cout, ++(*it)), " "), v[0])

This is a function call with two arguments, operator<<(std::cout, ++(*it)) and v[0]. The order in which function arguments are evaluated is unspecified, one platform or compiler may do it differently than another (left to right and right to left are common, as far as I know).

If the second argument is evaluated first, v[0] is retrieved while still holding 1, and we print 212.

If the first argument is evaluated first, ++(*it) happens first, and v[0] is retrieved after, so we print 222.

Unfortunately, the C++ standard only guarantees that the evaluation of all arguments is sequenced before the function body, but not with respect to each other.

Using both v[0] and ++v[0] in unsequenced expressions may invoke undefined behavior - which could do exactly what you want, or launch the missiles.

Upvotes: 1

user5473178
user5473178

Reputation:

The reason being,:

cout<<++(*it);

is printing the next value 2 but the original value of v increases only after the the line:

cout<<++(*it)<<" "<<v[0]<<" "; // v[0] is still `1`

Now the value v[0] is incremented and result is 2

cout<< v[0]<<" ";

You can increment before the cout

++(*it);
cout<<*it<<" "<<v[0]<<" ";

Now the output will be the same.

Upvotes: 2

Related Questions