Connecting Tech Pros Worldwide Help | Site Map

post and pre increment

Newbie
 
Join Date: Jan 2009
Posts: 2
#1: Jan 10 '09
what is difference between
1. y=++x++;
2. y=(++x)++;
3. y=++(x++);
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#2: Jan 10 '09

re: post and pre increment


Quote:

Originally Posted by jyots View Post

what is difference between
1. y=++x++;
2. y=(++x)++;
3. y=++(x++);

Have you tried to compile your examples? If so, you would've noticed that none of them compile. A ++ operator (pre- and post) takes an lvalue as its operand and its result is an rvalue so you can't apply two of them in a row.

kind regards,

Jos
Newbie
 
Join Date: Jan 2009
Posts: 2
#3: Jan 10 '09

re: post and pre increment


y=(++x)++;

this statement is givin no problem... but rest of them are givin error..
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#4: Jan 10 '09

re: post and pre increment


Quote:

Originally Posted by jyots View Post

y=(++x)++;

this statement is givin no problem... but rest of them are givin error..

That expression shouldn't compile either; if your compiler accepts it throw your compiler away and install a decent one. This is what the Standard has to say about it:

Quote:

Originally Posted by Standard 6.3.2.1

[#2] Except when it is the operand of the sizeof operator,
the unary & operator, the ++ operator, the -- operator, or
the left operand of the . operator or an assignment
operator, an lvalue that does not have array type is
converted to the value stored in the designated object (and
is no longer an lvalue)
. If the lvalue has qualified type,
the value has the unqualified version of the type of the
lvalue; otherwise, the value has the type of the lvalue. If
the lvalue has an incomplete type and does not have array

kind regards,

Jos
YarrOfDoom's Avatar
Expert
 
Join Date: Aug 2007
Location: Belgium
Posts: 1,118
#5: Jan 10 '09

re: post and pre increment


Same here on bcc32, got any suggestions on another (freeware) compiler to use?
Newbie
 
Join Date: Dec 2006
Posts: 26
#6: Jan 10 '09

re: post and pre increment


Download codeblocks it is free and update IDE and also come with mingw compiler
YarrOfDoom's Avatar
Expert
 
Join Date: Aug 2007
Location: Belgium
Posts: 1,118
#7: Jan 10 '09

re: post and pre increment


Tried it, with the same results. Are you sure about this Jos, because now you've already declared 2 quite well known compilers (as far as I know anything about it) to be not good.
Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,366
#8: Jan 10 '09

re: post and pre increment


This code:
Expand|Select|Wrap|Line Numbers
  1. y=++x++;       //ERROR
  2. y=(++x)++;     //OK
  3. y=++(x++);     //ERROR
  4.  
The postfix increment has a higher precedence so it goes first. The result of an x++ is not an l_value. That means you can't use it implicitly as an assignment. For that reason this code is also no good:
Expand|Select|Wrap|Line Numbers
  1. x++ = y;   //ERROR.
  2.  
However, y= y=(++x)++ is OK because the result of ++x is an l_value:
Expand|Select|Wrap|Line Numbers
  1. ++x = y;  //OK. 
  2.  
The reason for the difference is that the prefix operator actually changes the object whereas the postfix operator changes only a copy and that copy is not to be used as an l_value.

If your compiler rejects three of the examples, get a new compiler. Only the second example should compile.
Member
 
Join Date: Aug 2008
Posts: 121
#9: Jan 10 '09

re: post and pre increment


Quote:

Originally Posted by weaknessforcats View Post

This code:

Expand|Select|Wrap|Line Numbers
  1. y=++x++;       //ERROR
  2. y=(++x)++;     //OK
  3. y=++(x++);     //ERROR
  4.  
The postfix increment has a higher precedence so it goes first. The result of an x++ is not an l_value. That means you can't use it implicitly as an assignment. For that reason this code is also no good:
Expand|Select|Wrap|Line Numbers
  1. x++ = y;   //ERROR.
  2.  
However, y= y=(++x)++ is OK because the result of ++x is an l_value:
Expand|Select|Wrap|Line Numbers
  1. ++x = y;  //OK. 
  2.  
The reason for the difference is that the prefix operator actually changes the object whereas the postfix operator changes only a copy and that copy is not to be used as an l_value.

If your compiler rejects three of the examples, get a new compiler. Only the second example should compile.


No this is not correct:
Expand|Select|Wrap|Line Numbers
  1. ++x = y;
  • The result of a prefix incrementation operator is not an lvalue.
  • Postfix incrementation does not affect a copy of the operand but the operand itself. The difference, from the prefix incrementation, is the timing that the value is noted. As far as postfix incrementation is concerned, the value gets noted first and then the operand is incremented (++) or decremented (--) by 1.
YarrOfDoom's Avatar
Expert
 
Join Date: Aug 2007
Location: Belgium
Posts: 1,118
#10: Jan 10 '09

re: post and pre increment


Quote:

Originally Posted by Tassos Souris View Post

No this is not correct:

Expand|Select|Wrap|Line Numbers
  1. ++x = y;

It compiles without a problem though.
But if you try:
Expand|Select|Wrap|Line Numbers
  1. int x = 0;
  2. int y = 0;
  3. ++x = x;
  4. ++y = y+5;
  5. cout << x << " " << y;
Output when compiled with bcc32: 1 5
Output when compiled with mingw: 1 6
So which one is right, or is neither of them?
Member
 
Join Date: Aug 2008
Posts: 121
#11: Jan 10 '09

re: post and pre increment


Neither of them is correct. As Jos said the result is not a lvalue.
Visual Studio gives (correctly) a compile error:
Expand|Select|Wrap|Line Numbers
  1. error C2106: '=' : left operand must be l-value
  2.  
For example, consider this:
Expand|Select|Wrap|Line Numbers
  1. int x[ 2 ];
  2. int *ptr = x;
  3.  
This is not correct:
Expand|Select|Wrap|Line Numbers
  1. ++*ptr = 0;
  2.  
That is, because the 'result' of the assignment expression depends on the ++ operator. The zero (0) will be placed after the ++ has been 'resolved'. Of course, ++ does not produce a lvalue so a compile time error must be given by the compiler.

However, these are correct
Expand|Select|Wrap|Line Numbers
  1. *++ptr = 0;
  2. *ptr++ = 0;
  3.  
Because the 'result' of the assignment "does not depend" on the ++ operator.
Let's examine the first case:
Expand|Select|Wrap|Line Numbers
  1. *++ptr = 0;
... the ++ does not produce a lvalue but then the * operator takes effect so everything is ok
Expand|Select|Wrap|Line Numbers
  1. *ptr++ = 0;
... the value is noted first, * takes place and then the ++ is activated (which has no effect on the assignment).

So the problem is not where the ++ or -- are: on the left or on the right of the = operator. But, if the result that they do not produce a lvalue actually affects the assignment.
Needs Regular Fix
 
Join Date: Jul 2008
Posts: 381
#12: Jan 10 '09

re: post and pre increment


Quote:

Originally Posted by Tassos Souris View Post

Neither of them is correct. As Jos said the result is not a lvalue.

Jos said "...Except when it is the operand of the sizeof operator,
the unary & operator, the ++ operator..."

And i can quote(retype, as it's secured) 5.3.2.1 of the 14822 standard, regarding prefix ++/-- operator:
"The value is the new value of the operand; it is an lvalue"
You can
Expand|Select|Wrap|Line Numbers
  1.  printf("%p\n", &a );
  2.  printf("%p\n", &++a );
And it should print the same.
Member
 
Join Date: Aug 2008
Posts: 121
#13: Jan 10 '09

re: post and pre increment


Quote:

Originally Posted by newb16 View Post

Jos said "...Except when it is the operand of the sizeof operator,
the unary & operator, the ++ operator..."

And i can quote(retype, as it's secured) 5.3.2.1 of the 14822 standard, regarding prefix ++/-- operator:
"The value is the new value of the operand; it is an lvalue"
You can

Expand|Select|Wrap|Line Numbers
  1.  printf("%p\n", &a );
  2.  printf("%p\n", &++a );
And it should print the same.

Expand|Select|Wrap|Line Numbers
  1. &++a
  2.  
correct result:

Expand|Select|Wrap|Line Numbers
  1. '&' requires l-value
  2.  
++ on a does not produce a lvalue so the use of &++a is illegal.

And this is of course logical. What does ++a do? It increments 'a' and returns back the new value.. why do you want to get the address of that new value?? this is both illegal and not logical...

And is exactly what Jos stated...
Common English indicate that the expression Except when means 'every other case except this'. When used other than as a operand to the sizeof() operator (that means in all cases; including our examples) it does not produce an lvalue.

This is legal:
Expand|Select|Wrap|Line Numbers
  1. int y = 0;
  2. size_t size = sizeof( ++y );
  3.  
, and also, since the operand of the sizeof() operator is not evaluated if it is not a variable length array type, y remains 0.
Needs Regular Fix
 
Join Date: Jul 2008
Posts: 381
#14: Jan 11 '09

re: post and pre increment


Quote:

Originally Posted by Tassos Souris View Post

Expand|Select|Wrap|Line Numbers
  1. &++a
  2.  
correct result:

Expand|Select|Wrap|Line Numbers
  1. '&' requires l-value
  2.  
++ on a does not produce a lvalue so the use of &++a is illegal.

Compiler version, please. If it works contrary to what 5.3.2.1 of the 14822 standard says regarding prefix ++/-- operator:
"The value is the new value of the operand; it is an lvalue"

It works on old dos turbo c and on gcc 3.3.3 from cygwin.

Quote:
And this is of course logical. What does ++a do? It increments 'a' and returns back the new value.. why do you want to get the address of that new value?? this is both illegal and not logical...
Not only new value, but the variable itself that holds the new value. This is not the case of postfix one, when the old value is returned and the variable itself holds the new value.
Needs Regular Fix
 
Join Date: Jul 2008
Posts: 381
#15: Jan 11 '09

re: post and pre increment


Quote:

Originally Posted by YarrOfDoom View Post

++y = y+5;
So which one is right, or is neither of them?

The result of this expression is undefined, because compiler can add 5 to old value, increment y in left part, and then overwrite it with 5, or increment first and then calculate 1+5 and then assign; It happns because the only 'sequence point' here is at the end of the expression.
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#16: Jan 11 '09

re: post and pre increment


There's a difference between C and C++ here; I assumed C was being used by the OP and quoted the C Standard text. In C none of the expressions compile because none of the (pre and post) increment operators result in an lvalue.

C++ however treats both operators differently: the preincrement ++ operator seems to leave an lvalue; the postincrement ++ operator doesn't. While I agree that my assumption could've been totally wrong (about the language being used), the OP should've said which one actually was used.

kind regards,

Jos
Member
 
Join Date: Aug 2008
Posts: 121
#17: Jan 11 '09

re: post and pre increment


Well, clearly there was a difference in us about the language.
I referred to C99.. and newb99 probably to a C++ Standard... jyots was probably referring to C++ too..
Since i am not familiar with C++ standards i assumed that (since it is told C++ has compatibility with C) it would be the same...
Just wrong of us not to clarify the language and look at both languages as we should do...
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#18: Jan 11 '09

re: post and pre increment


Quote:

Originally Posted by Tassos Souris View Post

Well, clearly there was a difference in us about the language.
I referred to C99.. and newb99 probably to a C++ Standard... jyots was probably referring to C++ too..
Since i am not familiar with C++ standards i assumed that (since it is told C++ has compatibility with C) it would be the same...
Just wrong of us not to clarify the language and look at both languages as we should do...

Indeed; being a C person myself and *knowing* that none of the ++ nor -- operators yield an lvalue in any of the C versions (ranging from K&R1 up to the current version) I bluntly assumed that the OP was talking about C.

I heartly support splitting this forum in a C and C++ forum just to get rid of the confusion (we even get C# questions here because that also starts with a C ;-)

Assumptions are wrong of course but I fail to see what the benefit would be for the pre ++ operator yielding an lvalue:

Expand|Select|Wrap|Line Numbers
  1. int y= 42, x= 54;
  2.  
  3. ++y= x;
  4.  
Great, what's the benefit of ++y being an lvalue? It ends up with the value 54 anyway, effectively annihilating the pre increment ...

kind regards,

Jos

edit: I failed to find a satisfactory explanation in Bjarne Stroustrups brick of a book ...
Needs Regular Fix
 
Join Date: Jul 2008
Posts: 381
#19: Jan 12 '09

re: post and pre increment


Quote:

Originally Posted by JosAH View Post

Great, what's the benefit of ++y being an lvalue? It ends up with the value 54 anyway, effectively annihilating the pre increment ...

you can pass it by reference
Expand|Select|Wrap|Line Numbers
  1.  void bar(int &x);
  2. ...
  3. bar(++x); // is it different than x++;bar(x); ?
  4. //fail: bar(x++);
  5.  
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,165
#20: Jan 12 '09

re: post and pre increment


This

y=(++x)++; //OK

may be valid syntax and compilable in C++ but if x is a basic type, say an int, it still falls fowl of modifying a variable twice between sequence points and thus produces undefined behaviour.

On the other hand if x is an object with an overloaded operator++ then rather than being an actual operator it is a function call and it is not undefined behaviour, as there is a sequence point "At a function return, after the return value is copied into the calling context."

Needless to say this sort of silly coding structure is best avoided.
Member
 
Join Date: Aug 2008
Posts: 121
#21: Jan 12 '09

re: post and pre increment


isn't C++ fully backwards compatible with C (as much as i know.. i am not a fun of C++)?
How can there exist such a difference?
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#22: Jan 12 '09

re: post and pre increment


Quote:

Originally Posted by Tassos Souris View Post

isn't C++ fully backwards compatible with C

Nope; this is one of the peculiarities; there are more: quite a few of them handle widening conversions and the scope of variables. C and C++ are two different languages after all (although people may not realize this).

kind regards,

Jos
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,165
#23: Jan 12 '09

re: post and pre increment


No C and C++ are more like siblings than C++ a descendant of C. They have a large area of functionality that they both support but each language has things that are not part of the other Compatibility of C and C++ - Wikipedia, the free encyclopedia

Perhaps the easiest example of this is
int *pi = malloc(sizeof *pi);
which is completely valid C and in fact in C it would be best practice not to cast the output of malloc. This wont compile in C++ which doesn't allow assignment of non-equal pointers, it would require a cast.

The thing is people almost never compile C code as C++, most C++ compilers include a C compiler and when compiling a file with a .C extension compile it as C.
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#24: Jan 12 '09

re: post and pre increment


Quote:

Originally Posted by Banfa View Post

No C and C++ are more like siblings than C++ a descendant of C.

I didn't say that; all I said was that C and C++ are two different languages.

kind regards,

Jos
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,165
#25: Jan 12 '09

re: post and pre increment


Quote:

Originally Posted by JosAH View Post

I didn't say that;

I didn't say you did, that's my opinion, look at the post times.
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#26: Jan 12 '09

re: post and pre increment


Quote:

Originally Posted by Banfa View Post

I didn't say you did, that's my opinion, look at the post times.

Well, you *could've* typed that all in two minutes ;-)

kind regards,

Jos (<--- slow typer of the year)
Reply

Tags
post increment, pre increment