Anatoly
Anatoly

Reputation: 5241

In which precedence is this statement evaluated?

++*P--;

That is a question from an exam, if P a pointer to any element in an array, explain what this statement really does.

I even wrote a simple code to evaluate it:

  int i;
    int* array = calloc(10, sizeof(int));
    for (i = 0; i < 10; i++) {
        array[i] = i;
        printf("%d,", array[i]);
    }
    int* P = array + 5;
    printf("\n %p", P);
    printf("\n %d", *P);

    ++*P--;
    printf("\n %p", P);
    printf("\n %d \n", *P);
    for (i = 0; i < 10; i++) {
        printf("%d,", array[i]);
    }

But the output confuses me even more:

0,1,2,3,4,5,6,7,8,9,
 0x100105534
 5
 0x100105530
 4 
0,1,2,3,4,6,6,7,8,9,

It looks like it first dereferences P, then increases its value and then decreases value of pointer P, but why?

According to K&R table 2-1 from p53 (see the picture below) ++, --, and * (dereference) has the same precedence and associativity from right to left. So first step should be decreasing value of P, then dereference and then increasing dereferenced value, am I wrong?

enter image description here

Upvotes: 0

Views: 435

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

You can imagine this expression

++*P--

the following way

int *tmp = p;
--p;
int value = *tmp;
++value;

Here is a demonstrative program

#include <stdio.h>

int main( void )
{
    char s[] = "Hello World";
    char *p = s + 6;

    std::printf( "%c\n", ++*p-- );
    std::printf( "%s\n", s );

    p = s + 6;
    char *tmp = p--;
    char value = *tmp;
    ++value;

    std::printf( "%c\n", value );
    std::printf( "%s\n", s );
}

The program output is

X
Hello Xorld
Y
Hello Xorld

The difference in the outputting the string is that expression ++*p-- changes the string itself but expression ++value; changes a separate object. But the logic is similar.

Postfix expression p-- has the highest priority but its value is the value of p before decreasing.

Unary operators ++ and * in expression ++*p-- group right to left. So at first operator * is applied to the expression and after that operator ++ is applied.

Upvotes: 2

aschepler
aschepler

Reputation: 72463

You are correct that the precedence is

++(*(P--))

But note that the decrement is a postfix operation: even though the change to P happens first, the rest of the expression uses the old value of P. So in your example, first P is decremented to array+4, but the value of P-- is array+5, so array[5] gets incremented.

Upvotes: 3

Related Questions