473,698 Members | 2,239 Online

# return i++

Dear all,

sorry, I always forget this thing:

Is this foo:

int foo(int i)
{
++i;
return i-1;
}

the same like this foo:

int foo(int i)
{
return i++;
}

? As I am alway scared using the ++ operators in compact forms, I'd better

Thanks,
Patrick

*************** *************

[ ] both foos are identical in the functionality and well defined
[ ] keep your fingers away from "return i++"
[ ] keep your fingers away from "return ++i"
[ ] do not know

Jul 22 '05 #1
23 5728
Patrick Kowalzick wrote:
sorry, I always forget this thing:

Is this foo:

int foo(int i)
{
++i;
return i-1;
}

the same like this foo:

int foo(int i)
{
return i++;
}
Yes. And it really is the same as

int foo(int i)
{
return i;
}

? As I am alway scared using the ++ operators in compact forms, I'd better

Thanks,
Patrick

*************** *************

[ ] both foos are identical in the functionality and well defined
[ ] keep your fingers away from "return i++"
[ ] keep your fingers away from "return ++i"
[ ] do not know

You better mark the first one and the last one. Both answers are correct.

V
Jul 22 '05 #2
Dear Victor,
You better mark the first one and the last one. Both answers are correct.

[x] both foos are identical in the functionality and well defined
[ ] keep your fingers away from "return i++"
[ ] keep your fingers away from "return ++i"
[x] did not know

Thanks ;),
Patrick
Jul 22 '05 #3

int Blah()
{
int k = 5;

return ++k;
}
The above function returns 6.

--

The below function returns 5.

int Blah()
{
int k = 5;

return k++;
}

--

When you put ++ before the name: The object is incremented. The value of the
expression is the object's value *after* the increment.

When you putt ++ after the name: The value of the expression is the object's
value *before* the increment. The object is incremented.
Maybe the following will enlighten?:

class Number
{
private:

unsigned k;

public:

Number& operator++()
{
//This gets called when you do ++object
//Note that it returns by reference

k += 1;

return *this;
}

Number operator++(int)
{
//This gets called when you do object++
//Note that it returns by value

//First we create a temporary, making a copy of the current object
Number temp = *this;

//Now we proceed with the increment
k += 1;

//But... we return the old value, ie. before the increment
return temp;
}
};
-JKop
Jul 22 '05 #4
When you put ++ before the name: The object is incremented. The value
of the expression is the object's value *after* the increment.

When you putt ++ after the name: The value of the expression is the
object's value *before* the increment. The object is incremented.

Here's the simple way to remember it: Just read from left to right as
normal:
++object;

[increment], then [object];
object++;

[object], then [increment];
Hopefully you're not Arabic!
-JKop
Jul 22 '05 #5
Dear JKop,

thanks a lot for your explanations. Sorry that I did not express me right,
but I know the thing about post- and pre-increment.

The only problem I have, is to remember in which cases I run into undefined
behaviour. So I'd better ask before ;). The compilers are not a good
indicator here, because some may work, and others not (undefined).

I was only *quite* sure that my code is fine, but not 100%.

Thanks,
Patrick
Jul 22 '05 #6
Patrick Kowalzick wrote:

Dear JKop,

thanks a lot for your explanations. Sorry that I did not express me right,
but I know the thing about post- and pre-increment.

The only problem I have, is to remember in which cases I run into undefined
behaviour. So I'd better ask before ;).

In a nutshell:
* make sure the variable that gets incremented is not the same variable
assigned to.

i = i++; // <- That's a no, no

* don't increment the same variable more then once in a statement

j = i++ + i++; // no, no
foo( i++, i++ ); // no, no
cout << i++ << i++; // no, no

If you don't do any of the above you should be fairly safe
(Did I miss some other common mistakes?)

--
Karl Heinz Buchegger
Jul 22 '05 #7
JKop wrote:

When you put ++ before the name: The object is incremented. The value of the
expression is the object's value *after* the increment.

When you putt ++ after the name: The value of the expression is the object's
value *before* the increment. The object is incremented.

Actually, in both cases:
1. The object is incremented.
2. The value returned is either the original or
original value plus one.

You can't make any statement about WHEN the increment occurs.
Actually, I wouldn't have writen either ++k or k++.
Since I don't really care to change k, just get a value
one greater than it:

return k+1;
is MORE appropriate in my opinion.
Jul 22 '05 #8
Karl Heinz Buchegger wrote:
Patrick Kowalzick wrote:
Dear JKop,

thanks a lot for your explanations. Sorry that I did not express me right,
but I know the thing about post- and pre-increment.

The only problem I have, is to remember in which cases I run into undefined
behaviour. So I'd better ask before ;).

In a nutshell:
* make sure the variable that gets incremented is not the same variable
assigned to.

i = i++; // <- That's a no, no

* don't increment the same variable more then once in a statement

j = i++ + i++; // no, no
foo( i++, i++ ); // no, no
cout << i++ << i++; // no, no

If you don't do any of the above you should be fairly safe
(Did I miss some other common mistakes?)

Actually, variables is a bit too loose a requirement. It has to be
'object'. It is possible to increment the same object using different
variables:

int i = 42;
int& j = i;
i = j++; // same object, different variables

or even functions:

extern int i;

int foo() {
return i++;
}

int bar() {
i = foo(); // extremely obscured -- same object, and you don't
// even see the increment
}

V
Jul 22 '05 #9
Karl Heinz Buchegger wrote:
...
In a nutshell:
* make sure the variable that gets incremented is not the same variable
assigned to.

i = i++; // <- That's a no, no

* don't increment the same variable more then once in a statement

j = i++ + i++; // no, no
foo( i++, i++ ); // no, no
cout << i++ << i++; // no, no

If you don't do any of the above you should be fairly safe
(Did I miss some other common mistakes?)
...

You covered only the first part of the rule - multiple modifications
lead to UB. There's a second part as well - reading the old value for a
purpose other that calculating the new value leads to UB. For example

int i, j;
...
j = i++ + i; // no, no

Of course, it would also be useful to explain the difference between
built-in and user-defined operators (and when undefined behavior turns
into unspecified behavior) but I'm afraid we'll need a rather large
nutshell for all this.

--
Best regards,
Andrey Tarasevich
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.