tags:

views:

155

answers:

4

What precedence rules apply in parsing this expression:

*(c++);  // c is a pointer.

Thank you.

well, I tried the following

x = *c; c++;
x = (*c++);
x = *(c++);

They appear to be equivalent

+5  A: 

There are parentheses grouping the expression, so ++ is evaluated before *.

If the parentheses were removed to obtain *c++, then the expression would still be parsed as *(c++) and not as (*c)++ because of the precedence rules.

James McNellis
so *(c++) and *c++ are the same?
aaa
@aaa: Yes, they are, but if you think this might be confusing, there is nothing wrong with using parentheses to group the expression and make it clearer.
James McNellis
thank you.For some reason I thought *c++ made dereferenced first, but then I started getting incorrect results when using it and came here to ask
aaa
@James, it's exactly the other way around.
Nikolai N Fetissov
@Nikolai: No, it really isn't.
James McNellis
Yes, just realized that. You should mention that parsing order and evaluation order are different though.
Nikolai N Fetissov
@Nikolai: What difference is there? `++` is evaluated before the `*`; if it wasn't, then we would increment the referent, not the pointer. Several people seem to think the question has turned into "what is the behavior of the postfix increment operator?" That question is addressed in several other questions, e.g., [this one.](http://stackoverflow.com/questions/2395423).
James McNellis
The difference is that `*ptr++` is actually `tmp=ptr,ptr+=1,*tmp` and not `ptr+=1,*ptr`. Yes, the behavior of these two together.
Nikolai N Fetissov
@Nikolai: Exactly: that is the definition of the behavior of the postfix increment operator; its behavior does not change on account of it being in proximity to the indirection operator. If one is confused by this then as I said in a comment above, there is nothing wrong with adding parentheses to make the grouping explicit.
James McNellis
+2  A: 

The pointer increment is applied first because of the parentheses, then the dereference.

But, the return value of c++ is the value of c before the increment. So the return value of the expression *(c++) is the same as *c. For example:

char *c = "Hello";
char a, b;

a = *c;            // a is 'H'
b = *(c++);        // b is 'H', but now c is "ello"
MatthewD
This is incorrect. The postfix increment is practically invisible until the statement has been executed. This is why increments/decrements avoid much confusion when put on their own line whenever possible.
virstulte
The order I gave is correct. However, the return value of the `c++` operation is the value of `c` before the increment. This is why increment appears invisible.
MatthewD
@virstulte: Better?
MatthewD
Much clearer, now I totally agree with you here. Integrity restored, and upvoted :)
virstulte
+6  A: 

the ++ operator has not so much to do with precedence, but tells to increment only after evaluation.

So *c will be "returned" and then c will be incremented.

Please don't confuse precedence with order of execution!

mvds
OMG people, please... try it for yourself, work(*(c++)) is equivalent to work(*c);c++;really.
mvds
thank you.I tried and it seems to be so, like you say, (*(c++)) and (*c++) dereference before increment
aaa
trying to make things even more clear: "precendence" deals with the "glue" rules, and can be forced to behave in a way using parentheses (), much like in mathematics. ++ has higher precedence than * and thus glues a little harder to c in this case. ++c and c++ are used to execute before or after the value of c is used in the expression.Note that even *({c++;}) is evaluated as *c;c++;, but *({c++;c++;}) is evaluated as *(++c);c++;
mvds
+1  A: 

As mvds said: the "X++" operator is executed after the evaluation.

From C Language Reference: "When postfix ++ is applied to a modifiable lvalue, the result is the value of the object referred to by the lvalue. After the result is noted, the object is incremented by 1 (one). "

KikoV