Sign in to follow this  

why ++i return temp object on C?

This topic is 4660 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I find ++i return a rvalue object On C! I work with C++ a long time.first know it:( so (++i)++ is happy to C++. and (++i)++ is a error to C. I want to know :why C++ design ++i have differ behavior to C?

Share this post


Link to post
Share on other sites
Quote:
Original post by yjh1982
I find ++i return a rvalue object On C!
I work with C++ a long time.first know it:(


so (++i)++ is happy to C++.
and (++i)++ is a error to C.

I want to know :why C++ design ++i have differ behavior to C?


Because there different languages :P

The definitions of rvalues & lvalues are slighty different in C++ than C, C doesn't have reference types, pre-increment generally returns a non-constant reference type.

It gets even more complicated in C++/CLI where it also introduces GC-lvalues, handle types, tracking references on top of C++ l & rvalues :P

Share this post


Link to post
Share on other sites
Quote:
Original post by yjh1982
but why C++ let pre-increment return a non-constant reference?
only for (++i)++ expediency?


Probably to do with consistency & efficiency for stuff like operator overloading, think STL style iterators e.g:


struct iterator {

....
iterator& operator++() { //pre-increment
++current;
return *this;
}

iterator operator++(int) { //post-increment
iterator tmp = *this;
++current;
return tmp;
}
....
};

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
Quote:
Original post by yjh1982
but why C++ let pre-increment return a non-constant reference?
only for (++i)++ expediency?


Probably to do with consistency & efficiency for stuff like operator overloading, think STL style iterators e.g:


struct iterator {

....
iterator& operator++() { //pre-increment
++current;
return *this;
}

iterator operator++(int) { //post-increment
iterator tmp = *this;
++current;
return __tmp;
}
....
};


but before C++,later stl....if C++ not change pre-increment.
the stl can write to
...
iterator operator++() { //pre-increment
iterator tmp = *this;
++current;
return *this;
}

iterator operator++(int) { //post-increment
return operator++();
}

...
isn't it?

Share this post


Link to post
Share on other sites
increment SHOULD be an lvalue, period .. these 3 are the same (in C++ and in any sensible abstract langauge):

// assume int x;

a) (x = x + 1)
b) (x += 1)
c) (++x)

with the only exception that the first one can get into sync point trouble when mixed with postincrement type stuff more easily.

Share this post


Link to post
Share on other sites
Quote:
Original post by Xai
increment SHOULD be an lvalue, period .. these 3 are the same (in C++ and in any sensible abstract langauge):

// assume int x;

a) (x = x + 1)
b) (x += 1)
c) (++x)

with the only exception that the first one can get into sync point trouble when mixed with postincrement type stuff more easily.


excuse me.my mean is ++x is lvalue on C++,but not lvalue on C.
and I want to know reason for this change.

Share this post


Link to post
Share on other sites
why does it matter?

combining post an pre increments on a single line ought to have undefined results, and it does [msvc is different from gcc in this respect as well]

Share this post


Link to post
Share on other sites
Quote:
Original post by sit
why does it matter?

combining post an pre increments on a single line ought to have undefined results, and it does [msvc is different from gcc in this respect as well]


combining increments Only a Sample .
and there:
int a,b;
(a=b)=1;//error!


int i;
int *p=&++i;//error!


so you see.many difference.....

Share this post


Link to post
Share on other sites
Quote:
Original post by yjh1982
Quote:
Original post by Xai
increment SHOULD be an lvalue, period .. these 3 are the same (in C++ and in any sensible abstract langauge):

// assume int x;

a) (x = x + 1)
b) (x += 1)
c) (++x)

with the only exception that the first one can get into sync point trouble when mixed with postincrement type stuff more easily.


excuse me.my mean is ++x is lvalue on C++,but not lvalue on C.
and I want to know reason for this change.


as far as i know, C returned an rvalue cause that's the way the original creators made it in the first versions (you realize that the preincrement operator was created in the days of NON optimizing compilers right - and it was created NOT because they wanted to save typing, but because they wanted a way to tell the compiler to use the machine instruction which could increment a register / memory address more efficiently than the instruction which addeded 2 arbitrary numbers and stored the result in the first one). So the rvalue in C thing was not really an intentional design decision, just the way it worked (and nobody seemed to care either way really).

Then C++ added operator overloading, and references ... sudenly (++myObject).Foo() had to do something. Because EVEN as an rvalue, ++myObject would / should be able to call (and be passed to) functions. Once you can do these:

Foo(++myObject);
(++myObject).Foo();

then your really just not that different than an lvalue (cause those functions could change the value of the thing at the memory locations of myObject) ... so while this:

(++myObect) = anotherObject;

looks really really silly, since the language doesn't know what your shorthand means (maybe ++ increments the ref count :), they just decided to abstain from making a decision. By making it return an lvalue, the ways it will be used are totally up to you, the class writer and user.

Personally, using it as an lvalue doesn't appeal to me ... but there's my take on why (kind of) it might be that way. Sorry I couldn't be more conclusive, but I don't know the "real" answer in terms of historic discussions or anything.

Share this post


Link to post
Share on other sites
Quote:
Original post by yjh1982
so (++i)++ is happy to C++.

That is actually not happy to C++, where i is a a fundamental type. This is because while ++i returns an lvalue, there is also a rule that states that you can't alter the same data twice between sequence points. Your example therefore actualyl has undefined behavior (your computer could EXPLODE or it could work properly, or do nothing at all, etc.). It pretty much limits you to doing things such as pass the result to a function as a non-const reference. With respect to objects with overloaded operator++, however, you can use the object immediately after the ++ operation, since function calls and returns act as sequence points (whereas the built-in operator functionality is not a sequence point).

Share this post


Link to post
Share on other sites
Quote:
Original post by Polymorphic OOP
Quote:
Original post by yjh1982
so (++i)++ is happy to C++.

That is actually not happy to C++, where i is a a fundamental type. This is because while ++i returns an lvalue, there is also a rule that states that you can't alter the same data twice between sequence points. Your example therefore actualyl has undefined behavior (your computer could EXPLODE or it could work properly, or do nothing at all, etc.). It pretty much limits you to doing things such as pass the result to a function as a non-const reference. With respect to objects with overloaded operator++, however, you can use the object immediately after the ++ operation, since function calls and returns act as sequence points (whereas the built-in operator functionality is not a sequence point).


I can't understand....
I think your mean about "(++i,++i);"this is not happy behavior
(++i)++ in C++ is sure behavior pre (++i),after use result of (++i) to
after-increments------------------

under dev-cpp and vc6,open watom
#include <stdio.h>


int main(int argc, char* argv[])
{
int i=0;

printf("%d byebye!\n",(++i)++);
return 0;
}
all print 1


Share this post


Link to post
Share on other sites
Quote:
Original post by yjh1982
I can't understand....
I think your mean about "(++i,++i);"this is not happy behavior
(++i)++ in C++ is sure behavior pre (++i),after use result of (++i) to
after-increments------------------


No. It has undefined behaviour. You're not allowed to modify a variable twice in between sequence points. Parentheses do not introduce sequence points. ; and , do.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Quote:
Original post by yjh1982
I can't understand....
I think your mean about "(++i,++i);"this is not happy behavior
(++i)++ in C++ is sure behavior pre (++i),after use result of (++i) to
after-increments------------------


No. It has undefined behaviour. You're not allowed to modify a variable twice in between sequence points. Parentheses do not introduce sequence points. ; and , do.


To clarify, Fruny means operator, - not the function arguments seperator.

Share this post


Link to post
Share on other sites

This topic is 4660 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this