By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,492 Members | 1,283 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,492 IT Pros & Developers. It's quick & easy.

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

P: n/a
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
}

Sep 12 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
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?

Sep 12 '05 #2

P: n/a
lovecreatesbeauty wrote:
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.
}

};
Sep 12 '05 #3

P: n/a
John Fullman wrote:
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
Sep 12 '05 #4

P: n/a
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.

Sep 12 '05 #5

P: n/a
lovecreatesbeauty wrote:
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

Sep 12 '05 #6

P: n/a
lovecreatesbeauty wrote:
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.


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.

Sep 12 '05 #7

P: n/a
lovecreatesbeauty wrote:
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.
Sep 12 '05 #8

P: n/a
Kai-Uwe Bux wrote:
lovecreatesbeauty wrote:

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.


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

Sep 12 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.