return i++

P

Patrick Kowalzick

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
ask......

Thanks,
Patrick

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

Reply form:

[ ] 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

Please mark the correct answers. More than one answer might be correct.
 
V

Victor Bazarov

Patrick said:
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
ask......

Thanks,
Patrick

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

Reply form:

[ ] 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

Please mark the correct answers. More than one answer might be correct.

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

V
 
P

Patrick Kowalzick

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
 
J

JKop

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
 
J

JKop

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
 
P

Patrick Kowalzick

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
 
K

Karl Heinz Buchegger

Patrick said:
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?)
 
R

Ron Natalie

JKop said:
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.
 
V

Victor Bazarov

Karl said:
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
 
A

Andrey Tarasevich

Karl said:
...
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.
 
P

Patrick Kowalzick

Dear Victor, dear Karl Heinz,
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
}

thanks. I try to burn it in my brain and will ask again in 6 month.

Regards,
Patrick
 
P

Patrick Kowalzick

Dear Ron,
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.

Normaly I´d agree, but it is a counter :) and should definitly be
incremented.

Regards,
Patrick
 
A

Andrey Tarasevich

Victor said:
...
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
}
...

Although it is worth mentioning that this case is very different from
the previous ones and the behavior is perfectly defined and specified,
since the modifications of 'i' are separated from each other by at least
one sequence point.
 
V

Victor Bazarov

And I missed a return statement here...
Although it is worth mentioning that this case is very different from
the previous ones and the behavior is perfectly defined and specified,
since the modifications of 'i' are separated from each other by at least
one sequence point.

You're absolutely right, I must have been thinking of this:

------------------------ a.cc
extern int i;
void foo(int &j) {
j = i++;
}
------------------------ b.cc
void foo(int&);
extern int i;
void bar() {
foo(i);
}

which is essentially the same as the first one, only the reference and
the object are separated from each other by a module border, while still
referring to the same object.

V
 
H

Howard

Patrick Kowalzick said:
Dear Ron,


Normaly I4d agree, but it is a counter :) and should definitly be
incremented.

Regards,
Patrick

If your original function (pasted below) is the way you actually have it in
code, the your "counter" isn't getting incremented, because you pass i in by
value, then increment the local copy of it. If you meant to change the
value that was passed in, make sure you pass it by reference (or pointer):

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

should be:

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

-Howard
 
P

Patrick Kowalzick

Hi Howard,
If your original function (pasted below) is the way you actually have it in
code, the your "counter" isn't getting incremented, because you pass i in by
value, then increment the local copy of it. If you meant to change the
value that was passed in, make sure you pass it by reference (or pointer):

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

You are right, i missed a part. A more complete code looks like this:

int foo(int i)
{
static int i = 0;
return i++;
}

++Patrick--
 
V

Victor Bazarov

Patrick said:
Hi Howard,




You are right, i missed a part. A more complete code looks like this:

int foo(int i)
{
static int i = 0;
return i++;
}


Wow! Really? You have a local variable with the same name as the
argument? Why?

V
 
P

Patrick Kowalzick

Don´t bother me. Copy paste. :)
Wow! Really? You have a local variable with the same name as the
argument? Why?

Should be:

int foo()
{
static int i = 0;
return i++;
}

could be perhaps:

const int & foo()
{
static int i = 0;
return i++;
}

but I think there is no big difference....


Patrick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,813
Messages
2,569,696
Members
45,488
Latest member
MohammedHa

Latest Threads

Top