1

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:

Operator Precedence Source: "The C Programming Language (2nd Ed.)" by Dennis Ritchie et. al (pg. 53)

  • 2
    The operators postfix `++` and `->` have the *same* [precedence](https://learn.microsoft.com/en-us/cpp/c-language/precedence-and-order-of-evaluation?redirectedfrom=MSDN&view=msvc-160) but are evaluated from left to right. – Weather Vane Nov 19 '20 at 16:26
  • @WeatherVane Thanks for the information. It was not there in the std text books as my edit shows. –  Nov 19 '20 at 16:39
  • 2
    The C language was developed nearly 40 years ago, and was first standardised 30 years ago. It has evolved and refined, so it's important to use recent textbooks. Even so, some are bad. – Weather Vane Nov 19 '20 at 16:45
  • @WeatherVane could you please recommend me a good and recent one? –  Nov 19 '20 at 18:01
  • Please see [The Definitive C Book Guide and List](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) – Weather Vane Nov 19 '20 at 18:19

1 Answers1

3

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.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • thanks a lot for the information. It was not there in standard text books. –  Nov 19 '20 at 16:38