(*p)++ and *p++ differ by nothing but a pair of parentheses — and they do completely different things. One increments the value the pointer targets; the other moves the pointer itself. This question from our C Programming Quiz App checks whether you know which is which, and the answer comes down to operator precedence.
The Quiz Question
int a = 10;
int *p = &a;
(*p)++;
printf("%d", a);
What is printed by this code?
- 10
- 11
- Compile error
- Undefined behavior
The Correct Answer: 11
The parentheses force the dereference first: (*p) is the object p points to — the variable a — and the ++ then increments that object. Since p points at a, the statement is simply a++ in disguise. Verified on gcc 13.3 and Apple clang 21, warning-free under -Wall -Wextra:
$ gcc -Wall -Wextra inc.c && ./a.out 11
Why Each Wrong Answer Is Wrong
Why not 10?
10 is what you’d see if the increment had hit the pointer instead of the value — which is exactly what happens without the parentheses. Postfix ++ binds tighter than unary *, so *p++ parses as *(p++): increment the pointer, dereference its old value. We demonstrated with an array so the moved pointer still lands somewhere valid:
int arr[] = {10, 99};
int *p = arr;
int v = *p++; /* v = old *p; p moves to arr[1] */
printf("%d %d %d", v, arr[0], *p);
10 10 99
The yield is 10, arr[0] is still 10 — nothing was incremented except the pointer, which now sits on 99. That’s the behavior behind idioms like while (*dst++ = *src++); for string copy.
Why not “Compile error”?
(*p) is an lvalue of type int, and applying ++ to an int lvalue is ordinary C. Both compilers accept it silently.
Why not “Undefined behavior”?
Only one modification happens in the expression, so there’s no sequence-point violation. Compare with x++ + ++x — two unsequenced modifications of the same object — which genuinely is UB, as covered in our sequence points post. (*p)++ as a standalone statement is perfectly defined.
The Four Increment Forms, Side by Side
Precedence rule: postfix operators (++ after) bind tighter than unary operators (*, ++ before). Unary operators bind right-to-left. That gives four distinct combinations:
Expression Parses as Effect ────────── ────────── ───────────────────────────────────────── *p++ *(p++) move pointer forward; yield OLD target's value (*p)++ — increment the target value; yield its old value *++p *(++p) move pointer forward; yield NEW target's value ++*p ++(*p) increment the target value; yield the new value
Note that ++*p needs no parentheses to hit the value — both operators are unary, applied right-to-left, so the dereference happens first anyway. The parentheses in (*p)++ are needed only because postfix ++ would otherwise grab p first.
Frequently Asked Questions
What is the difference between *p++ and (*p)++?
*p++ increments the pointer and yields the value it pointed to before moving. (*p)++ leaves the pointer alone and increments the pointed-to value. The parentheses override postfix ++‘s higher precedence.
Is (*p)++ undefined behavior?
No. It performs a single modification of a single object — equivalent to a++ when p points at a. UB requires modifying the same object twice (or modifying and independently reading it) without a sequence point.
What does ++*p do?
Same target as (*p)++ — it increments the pointed-to value — but as a pre-increment it yields the new value. No parentheses needed, because unary operators apply right-to-left: dereference first, then increment.
Related Reading
- Pointers in C – Complete Guide
- Sequence Points in C – Why x++ + ++x Is Undefined
- Increment and Decrement Operators in C
- C Aptitude Questions and Answers
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
This question is #123 in the C Programming Quiz App — 155 questions with explanations covering operators, pointers, memory, and more.
Download on Google Play →