Prefix increment/decrement results in lvalue, but postfix one results in rvalue?

L

lovecreatesbeauty

Hello experts,

Why can this difference between prefix increment/decrement and
postfix increment/decrement reside in built-in operators for built-in
data types? Thanks.

// test.cpp
//
// >g++ test.cpp
// test.cpp: In function `int main()':
// test.cpp:21: non-lvalue in increment
// test.cpp:22: non-lvalue in decrement
//

#include <iostream>
using std::cout;

int main()
{
int i = 0;

cout << ++++++i;
cout << ------i;
cout << i++++++; // non-lvalue in increment
cout << i------; // non-lvalue in decrement
}
 
J

John Fullman

Prefix inc/dec changes that contents of the variable immediatley, which
means no additional variables would have to placed on the stack:
C++:
++++++i;
Assembly:
inc i
inc i
inc i

Postfic inc/dec delays changing the value of the variable until the end
of the line...

C++:
i++++++;
Assembly:
push i
mov eax, i
inc eax
push i
mov eax, i
inc eax
push i
mov eax, i
inc eax
pop i
pop i
pop i

if you walk through this logically, you will see that it makes no sense
to do a series of post inc/dec statements. They would just override
themselves when the pop instructions are called... so the compiler
doesn't let you do something that makes no sense.
anotherwords... i++++++ is the logical eqivelant of i++

Does that help?
 
G

Gianni Mariani

lovecreatesbeauty said:
Hello experts,

Why can this difference between prefix increment/decrement and
postfix increment/decrement reside in built-in operators for built-in
data types? Thanks.

// test.cpp
//
// >g++ test.cpp
// test.cpp: In function `int main()':
// test.cpp:21: non-lvalue in increment
// test.cpp:22: non-lvalue in decrement
//

#include <iostream>
using std::cout;

int main()
{
int i = 0;

cout << ++++++i;
cout << ------i;
cout << i++++++; // non-lvalue in increment
cout << i------; // non-lvalue in decrement
}

Think about how you would implement a post inc/dec operator vs a pre
dec/inc operator.

struct IntThing
{
int value;

IntThing( int v = 0 )
: value( v )
{
}

// post decrement
const IntThing operator -- ()
{
int value_tmp = value;
value = value + 1; // cannot return a reference because
// the actual value would be wrong !
return IntThing( value_tmp );
}

// pre decrement
IntThing & operator -- ( int )
{
value = value + 1;
return * this; // can simply return a reference.
}

};
 
J

John Harrison

John said:
Prefix inc/dec changes that contents of the variable immediatley, which
means no additional variables would have to placed on the stack:
C++:
++++++i;
Assembly:
inc i
inc i
inc i

Postfic inc/dec delays changing the value of the variable until the end
of the line...

That's exactly the explanation that ends up confusing newbies about
postfix increment. It's not even true.

All operators have two aspects, a return value and (optionally) a side
effect. Prefix and postfix increment have the side effect of
incrementing the variable, this side effect happens immediately, not at
'the end of the line'. Where they differ is in their return value.
Prefix returns the value of the variable after it was incremented,
postfix returns the value of the variable before it was incremented.
Because prefix return the current value of the variable it can return a
reference to that variable (i.e. an lvalue). Because postfix returns the
old value of the variable it cannot do this, therefore it must return an
rvalue.

This explanation works equally well for built-in types and classes.

john
 
L

lovecreatesbeauty

Thank Gianni. But in my demo code snippet the data type is built-in
`int'. Does standard-compliant compilers implement those prefix/postfix
increment/decrement operators also in that way actually.


Thank Fullman and Harrison. I don't consider your advice reliable. Even
in C, both ------i; and i------; are illegal. There should be something
special in C++ make the prefix one correct.
 
K

Kai-Uwe Bux

lovecreatesbeauty said:
Thank Gianni. But in my demo code snippet the data type is built-in
`int'. Does standard-compliant compilers implement those prefix/postfix
increment/decrement operators also in that way actually.


Thank Fullman and Harrison. I don't consider your advice reliable. Even
in C, both ------i; and i------; are illegal. There should be something
special in C++ make the prefix one correct.

The standard explains the difference in 5.2.6 and 5.3.2. The gist of it is,
as John Harrison already explained, that both, postfix and prefix -- want
their argument to be an lvalue, but only prefix -- returns an lvalue.

Now, that does not say that ----i is legit (there might be something about
sequence points and undefined behavior), but at least the compiler is not
required to complain.


Best

Kai-Uwe Bux
 
G

Gianni Mariani

lovecreatesbeauty said:
Thank Gianni. But in my demo code snippet the data type is built-in
`int'. Does standard-compliant compilers implement those prefix/postfix
increment/decrement operators also in that way actually.

Standard compliant compilers have to implement the standard.
 
R

Ron Natalie

lovecreatesbeauty said:
Thank Gianni. But in my demo code snippet the data type is built-in
`int'. Does standard-compliant compilers implement those prefix/postfix
increment/decrement operators also in that way actually.
No. They do not.

Most compilers would add 3 to the memory location.
 
O

Old Wolf

Kai-Uwe Bux said:
The standard explains the difference in 5.2.6 and 5.3.2. The gist of
it is, as John Harrison already explained, that both, postfix and
prefix -- want their argument to be an lvalue, but only prefix --
returns an lvalue.

Now, that does not say that ----i is legit (there might be something
about sequence points and undefined behavior), but at least the compiler
is not required to complain.

In fact, it clearly modifies 'i' twice without a sequence point
(causing undefined behaviour).
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top