Consider the code segment given below:
#include <stdio.h>
struct s
{
int x;
char c;
};
int main()
{
struct s x[2]={{1,'a'},{2,'b'}};
struct s * p;
p=x;
int a = p++ -> x; //line of doubt
printf("%d \n",a);
}
The output of the following code is 1
and it makes it clear that it is actually evaluated as :
int a = ((p++) -> x);
Now my question is, we know that in C , the binary ->
operator is having higher precedence than the unary ++
operator. But why is the effect such that the ++
is grouped first and then the ->
.
Is it so that being a binary operator it looks for the first operand to its left and it being p
the pairing is done as :
int a= *(p++ -> x);
But this includes with p
, p++
as a chunk and hence first p++
is considered, but I feel this explanation is a bit vague. Could anyone explain me the proper logic and along with it, could anyone recommend me any book from where I could practice more examples like this.
Edit: Thanks for the answers, actually I have studied C from the texts "The C Programming Language" by Dennis Ritchie et. al and also from "C- The Complete Reference" by Hebert Schildt. In both the texts the operator precedence is as shown:
Source: "The C Programming Language (2nd Ed.)" by Dennis Ritchie et. al (pg. 53)
The postfix increment operator ++
and the member-access-via-pointer operator ->
have the same precedence level, and they group left-to-right. So first p++
is evaluated, then (p++)->x
.
Section 6.5.2p1 of the C standard gives the following syntax declaration for postfix operators:
postfix-expression: primary-expression postfix-expression [ expression ] postfix-expression ( argument-expression-listopt ) postfix-expression . identifier postfix-expression -> identifier postfix-expression ++ postfix-expression -- ( type-name ) { initializer-list } ( type-name ) { initializer-list , }
Had you used the prefix increment operator, i.e. ++p->x
, that has lower precedence than ->
, grouping as ++(p->x)
. So you would end up getting the x
member from the object p
originally pointed to, then that member would be incremented with the expression evaluating to the incremented member.