Does *p++ increment after dereferencing?

28,302

Solution 1

There is no ordering between the increment and the dereference. However, the * operator applies to the result of p++, which is the original value of p prior to the increment.

Solution 2

In the operators table, you can see that the suffix operator ++ have higher place than the * unary operator.

Hence, *p++ increase p (and not *p), and return the value of the address that p contained before the increment (since it's the suffix ++).

But the order is implementation-depend. It may begin by dereferencing p, and then increase it, and it may store the old value of p, increase it, and then dereference the old value.

Solution 3

Try it. The program

#include <stdio.h>

int main(void) {
    int p[2];
    int *q = p;
    p[0] = 10;
    p[1] = 100;

    printf("%d\n", *q++);
    printf("%d\n", *q);

    return 0;
}

prints

10
100

showing that the ++ applies to p, not to *p, and that the increment happens after the dereference.

EDIT: (Thanks to @EricLippert for convincing me to pull out K & R)

Not only may there be a happens-after relationship, but according to K & R page 203, there must be:

A postfix expression followed by a ++ or -- operator is a postfix expression. The value of the expression of the expression is the value of the operand. After the value is noted, the operand is incremented (++) or decremented (--) by 1.

(emphasis mine)

Granted, I don't believe that K & R says anything about the semantics of C in the presence of multithreading (according to Wikipedia the pthreads specification was released in 1995), but for a single-threaded program K & R is pretty clear.

Solution 4

The postfix ++ and -- operators essentially have higher precedence than the prefix unary operators. Therefore, *p++ is equivalent to *(p++); it increments p, and returns the value which p pointed to before p was incremented.

To increment the value pointed to by p, use (*p)++ (or perhaps ++*p, if the evaluation order of the side effect doesn't matter).

Solution 5

Given q = *p++;, q gets the value that p pointed to before the increment. Another way to say it is that the value of the expression *p++ is the value that p pointed to before being incremented.

Share:
28,302

Related videos on Youtube

Temuz
Author by

Temuz

Updated on July 26, 2022

Comments

  • Temuz
    Temuz almost 2 years

    I'm not really sure what the order here is. Is it: 1) Dereference the value of pointer p after increasing it 2) Dereference the value of pointer p before increasing it

  • asaelr
    asaelr about 12 years
    It may find *p, increment p and assign the value of *p (that calculated first) to q
  • Caleb
    Caleb about 12 years
    @asaelr It's a fair point that the assignment may actually happen after the increment, but the effect is the same: q gets the value of *p before p is incremented.
  • asaelr
    asaelr about 12 years
    The effect is the same, but the question was what happens first.
  • Caleb
    Caleb about 12 years
    The question isn't concerned with assignment -- the OP is asking whether the increment or the dereference happens first. In any case, rewrote the answer to take your concern into account.
  • asaelr
    asaelr about 12 years
    Well, the deference may also be after the increment.
  • Caleb
    Caleb about 12 years
    @asaelr Sorry -- not sure why my first edit didn't quite stick. I tried to make that as clear as possible.
  • Eric Lippert
    Eric Lippert about 12 years
    Hold on a moment here. In C there certainly may be a "happens after" relationship; whether there is or not is an implementation detail of the compiler. A C compiler has broad discretion in choosing how to order side effects within a sequence point, and it may choose to do the side effect of a ++ after everything else if it wants to. A C# compiler does not have the same lattitude; the C# specification is very clear about precisely when that side effect must be observed. (Observed within one thread of execution; the order in which another thread observes the side effect is unspecified.)
  • blasrodri
    blasrodri over 6 years
    "the post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation" en.wikipedia.org/wiki/Increment_and_decrement_operators