increment operator query in vector

Pages: 12
Hi Forum,
While working on vectors, I came across this situation where I am not sure how values are evaluated. I guess I am missing some link for the usage of "for" loop.

Following are two different scenarios. Size of vector is 10

Scenario:1
1
2
3
4
5
6
7
8
......
....
 for(i=0;i<v.size();i++)
 {
   v[i] = i++;
   cout << "element of vector is\t"<<v[i]<<endl;
 }
...


element of vector is    0
element of vector is    0
element of vector is    0
element of vector is    0
element of vector is    0
//loop is printed only 5 times, I guess that's okay considering the condition but not sure why i is not being assigned in v[i], though value of i is getting incremented.

Scenario 2 : replaced i++ with "i+1". Things work fine.
1
2
3
4
5
6
for(i=0;i<v.size();i++)
 {
   v[i] = i+1;
   cout << "element of vector is\t"<<v[i]<<endl;
 }



element of vector is    1
element of vector is    2
element of vector is    3
element of vector is    4
element of vector is    5
element of vector is    6
element of vector is    7
element of vector is    8
element of vector is    9
element of vector is    10


Should't i++ behave the same way as i+1? Kindly help :)
See what happens if you use ++i



Same result? :S Not sure what you intend to ask. :)
i think that v[K] = K++; //or ++K is undefined behaviour.
Should't i++ behave the same way as i+1? Kindly help :)
Nope, i++ will modify 'i'.
Oops..Don't know what was I thinking. v[k]=k++ is undefined behavior? well in that case, I guess incrementing k and then assigned it to v[k] wont work. Thanks for the help :)
if you first increment, and then assign, like this:
1
2
foo1++;
foo2[foo1]=foo1;

or
1
2
foo1++;
foo2[foo1-1]/*if you want the same as foo1 before the increment*/=foo1

it is perfectly defined behavior, but in your example it is undefined.
(just a logic flaw)

1
2
3
4
5
for(i=0;i<v.size();i++) 
 {
   v[i] = i++;
   cout << "element of vector is\t"<<v[i]<<endl;
 }


When you enter the loop i = 0;
@ line 3 this happens:
First a copy of i is made (0). internally i is then incremented to 1. The copy is what is returned from the operator (0), 0 is then assigned to the index of i which is 0, this takes place before the operator++. At line 4, i now takes the value of the ++ operator modification of 1, I'm guessing you created this vector and put 0's in for the values, because at position [1] the vector holds a zero value.

Now next iteration, you've already incremented i inside the loop, the for control increments, i is now 2. @ line 3 same thing as above, vector index 2 assigns the value 2 from the ++ operator, on the following line i is now 3, you print out vector @ index 3, which is zero.

You loop only prints 5 because your control variable is incremented twice for each pass.

Postfix ++ operator works like this.
1
2
3
4
5
6
int operator++(int)
{
    int temp = *this; //Copy made
   ++*this;
   return temp;
}


Prefix works like this
1
2
3
4
int operator++()
{
   return *this+=1;  //the actual variable is returned as a copy.
}


Should't i++ behave the same way as i+1? Kindly help :)

i + 1 creates a temporary variable of type int that is the sum of i and 1, as ne555 has already stated, this does not modify i.
Last edited on
I mean that the situation is similar to foo = ++foo; //or foo++ , that is undefined behaviour
closed account (S6k9GNh0)
It is probably defined but given how expressions are interpreted, it can be confusing. Anyways, take these examples and notice the differences:

http://ideone.com/SwMVg
http://ideone.com/5RWdM

Problem solved. :P

EDIT: i+1; //Does nothing by itself is obviously not the same as i++; //Changes environment . Do not say or act as though they do, you will get confused.

EDIT2: Also, ++i tends to be faster in the case of no optimization because i++ requires and returns a temporary variable.
Last edited on
Ah yes. Is there somewhere in the stardard that says this, I'm trying to find it? I tested it out on my machine VS2010 vc90 and with a simple example whos copy assignment is a shallow assignment it works as expected. Of course I may just be getting lucky.
Last edited on
v[i] = i++;
There is no sequence point between the two uses of i so I'm pretty sure it's undefined behaviour.

closed account (S6k9GNh0)
v[i] is a sequence point, operator[] is used here. Although, I'm pretty sure this doesn't work with bare arrays...

EDIT: iirc, its something like this: http://ideone.com/Wgq1Y http://ideone.com/r6Pti
Last edited on
> v[i] = i++; There is no sequence point between the two uses of i
> so I'm pretty sure it's undefined behaviour.

Yes, it is. Interestingly, the standard uses a similar construct, with the same identifier names in an example:
void g(int i, int* v) {
i = v[i++]; // the behavior is undefined
// ... - IS


By the way, the term 'sequence point' is no longer used wrt C++ - instead, we have 'sequenced before', 'unsequenced' and 'indeterminately sequenced'.

In the full expression v[i] = i++ ;, the evaluation of operands of individual operators is unsequenced.
Last edited on
JLBorges, That example uses a pointer and not std::vector's operator[] which will behave more like a function call. I don't know if that makes a difference. I try reading the standard but it's not so easy.

My intuitive is that the expression i and the expression i++ can be evaluated in any order, or even overlap. I guess that is what you mean by unsequenced. So we don't really know what is the argument to operator[]? v[?] = i++;. That would make it undefined.
I think the argument they're trying to make is that v[i] is a function call here and function calls act as a sequence point. Of course, that only matters with regard to the function argument being evaluated before the function call. There is no sequence imposed on the evaluation of the argument with regard to other subexpressions that are not the function call.

In other words, i++ on the right could easily be done before i++ on the left. That wouldn't violate the requirement for the i++ on the left to be fully evaluated prior to the function call.
> I think the argument they're trying to make is that v[i] is a function call here and function calls act as a sequence point.

Repeat: The concept of a 'sequence point' does not exist in C++ (C++ today).


> JLBorges, That example uses a pointer and not std::vector's operator[] which will behave more like a function call.

It would behave exactly like a function call; and v[i] and ++i are indeterminately sequenced.

Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function. (Footnote: In other words, function executions do not interleave with each other.)

Several contexts in C++ cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit. ... The sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
Last edited on
I just was curious if ++i gave a different result.

I know that this will give different results.

1
2
3
4
5
6
7
8
9
10
11
int i=1;
cout << i++; //prints 1
cout << i;      //prints 2

int i=1;
cout << ++i; //prints 2
cout << i;      //prints 2

int i=1;
cout << i+1; //prints 2
cout << i;      //prints 1 


Last edited on
ne555 wrote:
I mean that the situation is similar to foo = ++foo; //or foo++ , that is undefined behaviour
Why? I've done some testing and am confused.

var++ makes a copy of var, increments the original, and returns the copy by value.
++var increments the original and returns the original by reference.

1
2
3
4
5
6
7
int a = 3, b = 3, c = 2;

a = a++; //a gets incremented to four but then set back to 3

b = ++b; //b gets incremented to four and then pointlessly set to itself

++c = ++c; //now, I agree that this is undefined 


Why do I get a == 4? (with he compiler I used all three went to four) Surely it doesn't assign the old value of a to itself and THEN perform the increment?
Last edited on
Why do I get a == 4? (with he compiler I used all three went to four) Surely it doesn't assign the old value of a to itself and THEN perform the increment?


i++ returns copy of i then increments i
++i increments i and returns incremented i

Last edited on
How can it return a value but then still do code after returning? When would that code run?
Pages: 12