Reputation: 24778
Expression is:
foo = *p++
I am looking for a guide/reference with examples that can explain these things.
I understand postfix ++
has higher precedence than indirection *
, so the expression is parsed as
*(p++)
But I am trying to get more clarity on the statement in GNU C reference manual Pg 40, that says:
Here p is incremented as a side effect of the expression, but foo takes the value of *(p++) rather than (*p)++, since the unary operators bind right to left.
Upvotes: 1
Views: 235
Reputation: 4433
The OP asked "how is evaluated" the expression *p++
.
One thing is precedence and another different thing is evaluation.
The expression p++
increments the value of the variable p
, but the value of the expression is he "old" value that p
had.
For example, consider that p
is char pointer used to analyze a string:
char s[] = "0123456789!";
char *p = s;
char q;
p = s; // Here *p == '0'
q = *p++ // Here q == '0' but *p == '1'
Although the precedence rules imply that *p++
is the same that *(p++)
, the value of *p++
is s[0]
, in despite of p == &s[1]
.
To be more precise, the value of the expression is the same as of *p
.
In this case, the "side effects" are referring to the operations that are done over the objects, in this case we have the objects p
and q
in the expression q = *p++
.
"Operation over objects" are not walking in the same path that "evaluation of expressions".
Upvotes: 2
Reputation: 272772
The GNU quote is misleading (IMHO); from a language point-of-view it's nothing to do with left-to-right (or vice versa).*
The C language standard doesn't define things in terms of precedence or associativity (left-to-right or right-to-left); these are merely implied by the defined grammar. Postfix ++
is classified as a postfix-expression rather than a unary-expression:
postfix-expression: primary-expression [...] postfix-expression ++ postfix-expression -- [...] unary-expression: postfix-expression ++ unary-expression -- unary-expression unary-operator cast-expression [...] unary-operator: & * + - ~ !
The interaction of the above production rules mean that your example is interpreted as *(p++)
.
In non-standardese, though, the reason is due to precedence, not associativity (which makes little sense for unary operators).
* In fact, the postfix operators are effectively left-to-right, which is the opposite of what's claimed.
Upvotes: 4
Reputation: 2618
In C/C++, precedence of Prefix ++ (or Prefix –) and dereference (*) operators is same, and precedence of Postfix ++ (or Postfix –) is higher than both Prefix ++ and *.
If p is a pointer then *p++ is equivalent to *(p++) (because postfix has higher precedence)
++*p is equivalent to ++(*p) (both Prefix ++ and * are right associative).
*++p is equivalent to *(++p) (both Prefix ++ and * are right associative).
You can see the below 2 programs to clarify your doubt.
Program 1
#include<stdio.h>
int main()
{
char arr[] = "overflow";
char *p = arr;
++*p;
printf(" %c", *p);
getchar();
return 0;
}
Output: p
Program 2
#include<stdio.h>
int main()
{
char arr[] = "overflow";
char *p = arr;
*p++;
printf(" %c", *p);
getchar();
return 0;
}
Output: v
Upvotes: 4
Reputation: 145899
Saying that postfix and unary operators are right-associative (bind right to left) is just another way to express the fact that postfix operators have higher precedence in C than unary operators.
Upvotes: 1