Question
Understanding the `-->` Pattern in C and C++
Question
I found this C/C++ code surprising because it compiles and runs successfully:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Its output is:
9 8 7 6 5 4 3 2 1 0
I expected --> to be some special operator, but apparently the code is valid in both C and C++. What exactly is happening here? How does the compiler parse this expression, where is this behavior defined by the language rules, and why does it work this way?
Short Answer
By the end of this page, you will understand that --> is not a special operator in C or C++. It is parsed as x-- > 0: a post-decrement followed by a greater-than comparison. You will learn how the expression is tokenized, why the loop prints 9 down to 0, how operator precedence and post-decrement work, and why this style is valid but usually avoided in production code for readability.
Concept
In C and C++, --> is not a single operator. The compiler reads this expression as two separate operators:
x--— post-decrement> 0— greater-than comparison
So this code:
x --> 0
means:
(x--) > 0
Why it works
The post-decrement operator returns the current value of x, and then decreases x by 1.
So if x starts at 10:
x--evaluates to10- then
xbecomes9 10 > 0is true, so the loop runs- inside the loop, printing
xshows9
This repeats until the old value of x is no longer greater than 0.
Why this matters
This example teaches several core language ideas:
- expressions are built from tokens and operators
- C and C++ do not invent a
-->operator here - post-decrement uses the old value before changing the variable
- the loop condition depends on the value returned by the expression, not just the final variable state
Understanding this helps you read compact C/C++ code correctly and avoid bugs caused by misunderstood increment/decrement expressions.
Mental Model
Think of x-- like handing someone your current counter value before lowering the counter by one.
Imagine a countdown clerk:
- The clerk shows the current ticket number.
- Then the clerk reduces the number by one.
- The program compares the shown number to
0.
So x --> 0 is like saying:
- “Show me the current value of
x” - “Now decrease
x” - “Was the shown value greater than 0?”
That is why the loop keeps running while the old value is above zero, even though the printed value inside the loop is already one smaller.
Syntax and Examples
Core syntax
x-- > 0
This is the same as:
(x--) > 0
It is not:
x --> 0 // special operator? No.
Example 1: basic countdown
#include <stdio.h>
int main()
{
int x = 5;
while (x-- > 0)
{
printf("%d ", x);
}
return 0;
}
Output:
4 3 2 1 0
Why?
- First check:
x--returns5, thenxbecomes4 5 > 0is true, so loop runs and prints4- Last successful check:
x--returns1, thenxbecomes0 1 > 0is true, so loop runs and prints0- Next check:
x--returns0, thenxbecomes-1 0 > 0is false, so loop ends
Example 2: compare with pre-decrement
#include <stdio.h>
int main()
{
int a = 5;
int b = 5;
while (a-- > 0)
{
printf("a: %d\n", a);
}
while (--b > 0)
{
printf("b: %d\n", b);
}
return 0;
}
Output:
a: 4
a: 3
a: 2
a: 1
a: 0
b: 4
b: 3
b: 2
b: 1
Difference
a-- > 0compares first, then decrements--b > 0decrements first, then compares
That is why a prints 0 but b does not.
Example 3: a clearer version
#include <stdio.h>
int main()
{
int x = 5;
while (x > 0)
{
x--;
printf("%d ", x);
}
return 0;
}
This is often easier for beginners to read, even though it behaves similarly.
Step by Step Execution
Consider this code:
#include <stdio.h>
int main()
{
int x = 3;
while (x-- > 0)
{
printf("%d\n", x);
}
return 0;
}
Step-by-step trace
Before the loop
x = 3
First condition check
x-- > 0
x--returns3- then
xbecomes2 - compare
3 > 0→ true - enter loop
- print
2
Second condition check
x--returns2- then
xbecomes1 - compare
2 > 0→ true - enter loop
- print
1
Third condition check
x--returns1- then
xbecomes0 - compare
1 > 0→ true - enter loop
- print
0
Fourth condition check
x--returns0- then
xbecomes-1 - compare
0 > 0→ false - loop stops
Final output
2
1
0
Key observation
The condition uses the old value of x, but the loop body sees the decremented value.
Real World Use Cases
You are unlikely to see x --> 0 used deliberately in serious code for style reasons, but the underlying concept is very common.
1. Countdown loops
for (int i = 10; i-- > 0; )
{
// process items from 9 down to 0
}
Useful when iterating backward through indexes.
2. Buffer or array processing in reverse
for (int i = length; i-- > 0; )
{
printf("%c\n", buffer[i]);
}
This visits length - 1 down to 0.
3. Retry logic
int retries = 3;
while (retries-- > 0)
{
// try operation
}
This means “keep trying while there are retries left.”
4. Resource draining or batch processing
while (remaining-- > 0)
{
// process one item
}
This is common when the old value is needed for the decision and the updated value is used afterward.
5. Parsing or low-level systems code
In C and C++, compact decrement conditions sometimes appear in:
- embedded code
- performance-sensitive loops
- legacy codebases
- parsers and token scanners
Even there, teams often prefer clearer formatting such as x-- > 0 rather than x --> 0.
Real Codebase Usage
In real projects, developers usually apply this idea in clearer forms.
Common pattern: reverse loops
for (int i = count; i-- > 0; )
{
use(items[i]);
}
This avoids off-by-one mistakes when counting backward.
Common pattern: guard-style counting
if (retries-- <= 0)
{
return false;
}
This uses the current value for a decision, then updates it.
Common pattern: validation and limits
while (remaining-- > 0 && read_next_chunk())
{
process_chunk();
}
This is compact, but should be used carefully because combining side effects and logic can reduce readability.
Team style in production code
Many teams prefer these alternatives:
while (x > 0)
{
--x;
printf("%d ", x);
}
or
for (int i = x - 1; i >= 0; --i)
{
printf("%d ", i);
}
These are more explicit and easier to review.
Best practice
- Use compact decrement expressions only when they are immediately clear.
- Avoid clever formatting like
-->if it may confuse readers. - Prefer readability over operator tricks.
Common Mistakes
1. Thinking --> is a real operator
Broken assumption:
// There is no special --> operator in C or C++
Correct understanding:
x-- > 0
It is just two operators placed next to each other.
2. Forgetting that post-decrement returns the old value
int x = 3;
printf("%d\n", x--); // prints 3
printf("%d\n", x); // now x is 2
If you expect the first print to be 2, you wanted --x instead.
3. Mixing pre-decrement and post-decrement mentally
int a = 3;
int b = 3;
printf("%d\n", a--); // 3
printf("%d\n", --b); // 2
a--uses the old value--buses the new value
4. Writing expressions that are too clever
Hard to read:
while (x-- > 0 && arr[x] != target)
{
}
Safer, clearer version:
while (x > 0)
{
--x;
if (arr[x] == target)
{
break;
}
}
5. Off-by-one errors in reverse loops
Broken code:
int i = 5;
while (--i > 0)
{
printf("%d ", i);
}
Output:
4 3 2 1
This skips 0.
If you want 0 included, use:
int i = 5;
while (i-- > 0)
{
printf("%d ", i);
}
6. Using unsigned integers without care
unsigned int x = 3;
while (x-- > 0)
{
printf("%u ", x);
}
After reaching 0, unsigned values wrap around to a large value when decremented. The loop condition still stops correctly here, but unsigned reverse loops are a common source of bugs in related patterns.
Be extra careful with types like size_t when counting backward.
Comparisons
Related operator comparisons
| Expression | What happens first? | Value used in comparison | Typical effect |
|---|---|---|---|
x-- > 0 | Compare old x, then decrement | Old value | Includes 0 in printed countdown body |
--x > 0 | Decrement first, then compare | New value | Usually stops before body sees 0 |
x > 0 then --x inside loop | Comparison and decrement are separate | Clearer control flow | Easier to read |
x-- > 0 vs --x > 0
int x = 3;
while (x-- > 0)
{
printf("%d ", x);
}
Output:
2 1 0
int x = 3;
while (--x > 0)
{
printf("%d ", x);
}
Output:
2 1
Compact vs explicit style
| Style | Example | Advantage | Disadvantage |
|---|---|---|---|
| Compact | while (x-- > 0) | Short, idiomatic to experienced C/C++ developers | Easy for beginners to misread |
| Explicit | while (x > 0) { --x; } | Clearer intent | Slightly more verbose |
Reverse for loop | for (int i = n; i-- > 0; ) | Good for index-based loops | Still needs comfort with post-decrement |
Token sequence vs imaginary operator
| Text | Actual meaning |
|---|---|
--> | -- followed by > |
>= | One real operator |
== | One real operator |
-> | One real operator used for member access through pointers |
This is a good reminder that some adjacent symbols form real operators, while others are simply separate tokens placed next to each other.
Cheat Sheet
Quick reference
x --> 0 means
x-- > 0
It is parsed as
(x--) > 0
Post-decrement rules
x--
- returns the current value of
x - then decreases
xby 1
Pre-decrement rules
--x
- decreases
xby 1 first - then returns the new value
Example
int x = 3;
while (x-- > 0)
{
printf("%d ", x);
}
Output:
2 1 0
Why it works
- condition checks old value
- loop body sees decremented value
Readability note
Prefer this spacing if you use it:
x-- > 0
Avoid writing:
x --> 0
because it looks like a special operator when it is not.
Common safe alternative
while (x > 0)
{
--x;
}
Important edge case
Be careful with unsigned types in reverse loops.
FAQ
Is --> an operator in C or C++?
No. It is not a real operator. The compiler reads it as -- followed by >.
Why does while (x-- > 0) print 0?
Because the comparison uses the old value of x, but inside the loop x has already been decremented.
What is the difference between x-- > 0 and --x > 0?
x-- > 0 compares first and decrements after. --x > 0 decrements first and then compares.
Is this valid in both C and C++?
Yes. The behavior comes from the normal rules for decrement operators and comparisons in both languages.
Should I write x --> 0 in production code?
Usually no. Even though it is valid, many readers may find it confusing. x-- > 0 or a more explicit loop is clearer.
Where is this defined in the language?
It follows from the standard rules for lexical tokenization and expression parsing: -- is the postfix decrement operator, > is the greater-than operator, and postfix operators bind tightly in expressions.
Does the compiler treat this as a joke or special shortcut?
No. There is no special case. It is simply standard parsing of normal operators.
Is x --> 0 the same as x -> 0?
No. -> is a real operator used to access a member through a pointer. --> in this example is not related to that.
Mini Project
Description
Build a small countdown program that demonstrates the difference between post-decrement and pre-decrement in loop conditions. This helps you see exactly how x-- > 0 behaves and why it is different from --x > 0 in real code.
Goal
Create a program that prints two countdowns: one using post-decrement and one using pre-decrement, so you can compare their outputs.
Requirements
- Create one loop using
x-- > 0 - Create another loop using
--x > 0 - Print the values produced by each loop clearly
- Use separate variables so the loops do not affect each other
- Make the program compile and run as standard C or C++
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.