o o
o o

Reputation: 155

operator precedence from page132 in K&R

I'm reading K&R and I got stuck in the following sentence.

*p -> str++ increments str after accessing whatever it points to (just like *s++)

I agree what it said for *p -> str++, but for *s++, it doesn't make any sense to me. I think *s++ will access whatever it points to AFTER incrementing s, just like (*s)++

Upvotes: 0

Views: 180

Answers (4)

Oka
Oka

Reputation: 26365

-> and postfix ++ both have higher precedence than *, with left-to-right associativity.

The expression *p->str++ can be read firstly as *(p->str)++, which makes semantically the same as *s++, which in turn can be read as *(s++). So yes, the indirection will occur after the incrementation (expr++), but

The result of the postfix increment and decrement operators is the value of expr.

Thus,

  • p->str, or s, yields a modifiable lvalue appropriate for ++ (a pointer type in this instance).

  • ++ (postfix) then increments this value in-place, evaluating to the value of the expression before incrementation.

  • * performs indirection on this pointer value.

Whereas, (*s)++ will perform indirection before incrementing the resulting value.

Upvotes: 3

John Bode
John Bode

Reputation: 123558

I think *s++ will access whatever it points to AFTER incrementing s, just like (*s)++

Nope. *s++ is parsed as *(s++) - you are dereferencing the result of s++. The result of s++ is the current value of s; the side effect of incrementing s does not affect the result. Logically, it works like

tmp = s
x = *tmp   // where "x =" represents any operation using the value of *tmp
s = s + 1

with the caveat that the last two operations can happen in any order, even simultaneously (interleaved or in parallel if the architecture supports it).

(*s)++ increments the result of *s - it's logically equivalent to writing

tmp = *s
x = tmp     // same as above
*s = *s + 1

with the same caveat as above.

Upvotes: 0

Ted Lyngmo
Ted Lyngmo

Reputation: 117658

I think *s++ will access whatever it points to AFTER incrementing s, just like (*s)++

This will increase the pointer by one:

*s++;

This will increase the dereferenced pointer (that is, what it's pointing at) by one:

(*s)++;

so, it's not the same thing.

Example:

#include <stdio.h>

int main() {
    char string[] = "Hello";
    
    char *s1 = string;

    printf("%c\n", *s1++);          // 'H'
    printf("%c\n", *s1);            // 'e'
    printf("%s\n", s1);             // "ello"

    char *s2 = string;

    printf("%c\n", (*s2)++);        // 'H'
    printf("%c\n", *s2);            // 'I'  ('H' + 1 = 'I')
    printf("%s\n", s2);             // "Iello"
}

Upvotes: 0

4386427
4386427

Reputation: 44329

The important thing here is the return value of s++. You need to recall that the return value of s++ is s. So the * will dereference the address s has before the increment.

So the code *s++ is the equivalent to

T* temp = s; \___ These two lines is what s++ is doing
s = s + 1;   /
*temp;

i.e. *s++ reads what s points to and increments s by one.

Note: To increment s before reading what it points to, you can do *++s.

Upvotes: 1

Related Questions