472,146 Members | 1,317 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,146 software developers and data experts.

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

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
8 6124
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
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
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
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
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
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
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
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.

Similar topics

6 posts views Thread by Sergey | last post: by
2 posts views Thread by Christian Christmann | last post: by
8 posts views Thread by Angel Tsankov | last post: by
6 posts views Thread by LuciferLeo | last post: by
8 posts views Thread by subramanian100in | last post: by
3 posts views Thread by subramanian100in | last post: by
3 posts views Thread by news.aioe.org | last post: by
reply views Thread by Saiars | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.