1

Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

#include<stdio.h>

int main()
{
  char a[]="Hello";
  char *p=a;
  while(*p)
    ++*p++;     //Statement 2
    printf("%s",a);
    int x=10;
    ++x++; //Statement 1
   return 0;
}

When i compile this code i get an l-value Required error in Statement 1, which i can understand. How is that statement 2 does not produce an error even though i intend to do the same thing? Can someone shed light?

Community
  • 1
  • 1
Vignesh_dino
  • 313
  • 2
  • 6

3 Answers3

3

Both pre-increment and post-increment produce rvalues and rvalues can't be modified.

So ++x++ (statement 1) is clearly a constraint violation and compiler gives error.

But it's not the case with the statement 2. Though p++ produces an rvalue which its value can't be modified, it can be dereferenced. Alternatively if you do ++p++ this would be equivalent to the ++x++ case and would give an error. Because here the pointer itself is modified.

So it's equivalent to: ++(*p++).

(Note that the brackets are only for understanding and it's not required. The expression ++*p++ is well-defined.)

What happens is:

  • The post-increment p++ evaluates to the old value of p, in this example &a[0], and the stored value of p is incremented.
  • *p++ gives the value p pointed to before the increment, in this example a[0].
  • The final pre-increment increments that value, so a[0] becomes I (probably, could be something else on EBCDIC machines).

When the incremented values of p and a[0] are stored is unspecified, but both must have been stored at the next sequence point (the terminating ;).

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
P.P
  • 117,907
  • 20
  • 175
  • 238
  • You have a bad formulation with "which was dereferenced by the post-increment". I know you mean the correct thing, and I don't know how to put it well, but that reads wrong. (I upvote in anticipation of an improved formulation.) – Daniel Fischer Dec 13 '12 at 13:50
  • @DanielFischer I was kind of felt that when I wrote it. Not really sure how to re-word it. Does it look better? – P.P Dec 13 '12 at 13:57
  • I have tried to explain it better, if you don't like it at all, roll back. – Daniel Fischer Dec 13 '12 at 14:07
  • @DanielFischer Thanks. Looks much clearer than what I had. Never thought writing the expression `++*p++` in plain English would be so hard :) – P.P Dec 13 '12 at 14:13
0

Quoting from ISO C99 standard :

6.5.2.4 Postfix increment and decrement operators

Constraints
1
The operand of the postfix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue.

For this case :

++*p++;     //Statement 2

postfix ++ has higher precedence and prefix ++ and * has same precedence and right to left associativity. It means at first step it's incrementing the pointer not it's value. So it will give you the next address of that type. And then value (which is actually *p) is incremented. So ,In this case no constraint violation. It's same as ++(*(p++)).

For other case below:

 int x=10;
 ++x++; //Statement 1

In the above case of variable(not pointer) ++(Either postfix or prefix increment or decrement) give you the rvalue ,then applying ++ or -- on rvalue is constraint violation.++ or -- operand should be an lvalue . See the Standard quote written above. Hence giving error.

Omkant
  • 9,018
  • 8
  • 39
  • 59
  • Postfix ++ has higher precedence than unary * and prefix ++ both. You seem to have confused this. No matter, the code is undefined behavior, so it doesn't fill any purpose trying to figure out what it will do. – Lundin Dec 13 '12 at 13:40
  • @Lundin : Don't pretty sure about undefined behavior but `++` and `*` has same precedence... – Omkant Dec 13 '12 at 13:44
  • @Lundin : The C programming by `K & R` in chapter 2 `2.12 Precedence and Order of Evaluation` see the table of operators given.And what the problem with `++(*(p++))` expression , can you please explain ? – Omkant Dec 13 '12 at 13:48
  • You have 3 different operators, postfix ++, prefix ++ and unary *. Their precedence is specified in C11 6.5/3: `The grouping of operators and operands is indicated by the syntax`. This means, the order of operator appearance in the C standard chapter 6.5 states the operator's precedence. Postfix ++ appears in 6.5.2 so it has higher precedence than prefix ++ and unary *, the latter two appear in 6.5.3 and have the same precedence, but are evaluated right-to-left in relation to each other. – Lundin Dec 13 '12 at 13:49
  • `++(*(p++))` : p++ the next address, then `*(p++)` will be the value of that address and then `++(*(p++))` will give you the incremented value. I have parsed like this , Am I wrong ? – Omkant Dec 13 '12 at 13:50
  • "value( which is `*p`) at that new address", no it's `*p` at the **old** address. `p++` evaluates to the not-incremented pointer. – Daniel Fischer Dec 13 '12 at 13:57
  • @Omkant The precedence table in K&R is plain wrong, it is known to be one of the greatest errors in that book (that saying a lot, since there are so many errors in it). – Lundin Dec 13 '12 at 14:00
  • @Omkant And yes, you are wrong, p++ will increment p to the next address, but only at the end of the expression (even though it is evaluated first). *p++ will be the value of the address before p++ is evaluated. And then ++*p will increase that value. – Lundin Dec 13 '12 at 14:03
  • @Lundin : Thanks I corrected that. Can you please tell me about where is it saying that K&R table is wrong ? No offence , Just wanted for future reference.Is it corrected in next edition of this book ? I am still referring that book for C language. One more Personal query - Which book or reference should I prefer other than ISO C-standard or standard itself is enough ? – Omkant Dec 13 '12 at 14:06
  • The C standard says that postfix operators have higher precedence than unary (prefix) operators, which in turn have higher priority than the cast operator. But K&R say that they are all the same, which is plain wrong. – Lundin Dec 13 '12 at 14:10
  • I have no book recommendations. The standard is of course canon, if you can cope with the technical, complex reading. There's a [book recommendation list](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) on SO. I would particularly stay away from K&R, Programmming Pearls and anything written by Schildt. – Lundin Dec 13 '12 at 14:15
0
#include<stdio.h>

int main()
{
  char a[]="Hello";
  char *p=a;
  while(*p)
    ++*p++;     //Statement 2
    printf("%s",a);
    int x=10;
    ++x=x++; //Statement 1
   return 0;
}

//this code will fetch same error due to the simultaneous pre and post increment. because it cannot assign and increment simultaneously it require a value to perform increment on it.