Ankur Agarwal
Ankur Agarwal

Reputation: 24778

How is this C expression evaluated

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

Answers (4)

pablo1977
pablo1977

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

Oliver Charlesworth
Oliver Charlesworth

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

Ayush
Ayush

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

ouah
ouah

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

Related Questions