What is the ‘–>’ operator in C/C++? I discovered this syntax in a discussion about hidden features of C++/STL, and it compiled and worked in both Visual Studio 2008 and G++ 4.4. Here’s the code example:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Output:
9 8 7 6 5 4 3 2 1 0
Where is this defined in the C/C++ standard, and what is its origin?
The -->
syntax in your code example is not actually a single operator in C/C++. It’s a clever visual trick that results from how the compiler parses tokens and applies operator precedence. The code x --> 0
is interpreted by the compiler as x-- > 0
, meaning “decrement x and then check if the result is greater than 0”.
Contents
- How the
-->
Syntax Actually Works - Operator Precedence and Token Parsing
- Where This Is Defined in the Standards
- Historical Origin and Community Culture
- Practical Examples and Similar Cases
- Best Practices and Clear Alternatives
How the -->
Syntax Actually Works
The expression x --> 0
is parsed by the C/C++ compiler as x-- > 0
, which breaks down into two operations:
x--
: Post-decrement operator, which uses the current value of x and then decrements it by 1> 0
: Greater-than comparison operator
In your example:
int x = 10;
while (x --> 0)
{
printf("%d ", x);
}
The loop executes as follows:
- First iteration: x is 10, condition 10 > 0 is true, prints 9 (x was decremented after evaluation)
- Second iteration: x is 9, condition 9 > 0 is true, prints 8
- …
- Tenth iteration: x is 1, condition 1 > 0 is true, prints 0
- Next check: x is 0, condition 0 > 0 is false, loop exits
That’s why the output is 9 8 7 6 5 4 3 2 1 0
rather than including 10 or stopping before 0.
Operator Precedence and Token Parsing
This behavior stems from fundamental C/C++ language rules:
Tokenization
The compiler first breaks the source code into tokens. In x-->0
, the tokens are:
x
(identifier)--
(post-decrement operator)>
(greater-than operator)0
(integer literal)
Operator Precedence
The C/C++ language defines operator precedence to determine the order of operations:
- Post-increment and post-decrement operators (
++
and--
) have higher precedence than comparison operators - The
>
operator has higher precedence than assignment operators but lower than decrement operators
Evaluation Order
The expression x-- > 0
is equivalent to (x--) > 0
due to precedence rules, and evaluates as:
- The current value of x is used for the comparison
- After the comparison, x is decremented by 1
Where This Is Defined in the Standards
This syntax isn’t defined as a special operator in either the C or C++ standards. Instead, it’s a consequence of three separate language specifications:
C Standard (ISO/IEC 9899)
The behavior comes from:
- 6.4.4 (Punctuators): Defines
--
and>
as separate punctuators (tokens) - 6.5.3 (Postfix increment and decrement operators): Specifies the behavior of the
--
operator - 6.5.8 (Relational operators): Specifies the behavior of the
>
operator - 6.5.14 (Boolean negation): Implicitly defines operator precedence
C++ Standard (ISO/IEC 14882)
Similarly in C++:
- [lex.punct] (Punctuators): Defines
--
and>
as separate tokens - [expr.post] (Postfix expressions): Specifies the post-decrement operator
- [expr.rel] (Relational operators): Specifies the greater-than operator
- [expr.operator] (Operators): Defines operator precedence
The standards don’t mention any special -->
operator because none exists—it’s purely a parsing artifact.
Historical Origin and Community Culture
Origins in Early C
This syntax quirk has been around since early versions of C in the 1970s-1980s. It emerged naturally from the language’s design choices:
- Tokenization rules that separate operators based on character sequences
- Operator precedence that places
--
above>
- Whitespace insensitivity that allows minimal spacing between
-
and>
Community Culture
This construct became a famous “Easter egg” or “gotcha” in the programming community:
- Often appears in “hidden features of C/C++” discussions
- Used as an interview question to test understanding of operator precedence
- Featured in programming forums and language trivia collections
- Demonstrates how human visual parsing can differ from compiler parsing
Dennis Ritchie, creator of C, reportedly mentioned that such edge cases were unintentional consequences of the language’s design rather than deliberate features.
The fact that it works across different compilers (like Visual Studio and G++ as you noted) confirms it’s based on core language specifications, not implementation-specific behavior.
Practical Examples and Similar Cases
More Examples of Operator Precedence “Tricks”
Here are other similar constructs that leverage operator precedence:
// This parses as a++ + ++b, not a+++ ++b
int a = 1, b = 1;
int result = a+++++b; // Valid syntax! Equivalent to (a++) + (++b)
// This parses as x = (y = 5), not (x = y) = 5
int x, y;
x = y = 5; // Valid assignment chaining
// This is a comparison, not assignment
if (x = 5) { /* executes */ } // Common bug! Should be if (x == 5)
Visual Similarity to Other Operators
The -->
syntax is particularly deceptive because:
- It visually resembles the
->
operator (member access through pointer) - It resembles an arrow suggesting “going to” zero
- The minimal spacing makes it appear as a single token
In fact, some early programming languages did have arrow-like operators (like Pascal’s ↑
for exponentiation), but C/C++ never defined -->
as such.
Best Practices and Clear Alternatives
While the -->
construct works, it’s generally considered poor style for several reasons:
Why to Avoid It
- Readability: Confuses most programmers at first glance
- Maintenance: Creates issues when others maintain your code
- Intent Unclear: Doesn’t clearly express what the code is doing
- Style Violation: Goes against most coding standards that favor clarity
Better Alternatives
For decrementing loops, consider these clearer options:
// Explicit post-decrement with clear spacing
while (x-- > 0) {
printf("%d ", x);
}
// Separate decrement from comparison
while (x > 0) {
printf("%d ", x - 1);
x--;
}
// For loop (most idiomatic for this case)
for (int i = 9; i >= 0; i--) {
printf("%d ", i);
}
When Might It Be Acceptable?
In rare cases where:
- You’re working with constrained code size in embedded systems
- You’re deliberately obfuscating code for security purposes
- You’re following a consistent established style in a specific codebase
- You’re creating code as an example or puzzle (as in your case)
Even then, adding a comment explaining the construct is good practice:
/* Post-decrement x and check if result > 0 */
while (x --> 0) {
printf("%d ", x);
}
Conclusion
The -->
syntax is not a special operator in C/C++ but rather a visual quirk resulting from how the compiler parses tokens and applies operator precedence. The expression x --> 0
is simply x-- > 0
, which decrements x after checking if it’s greater than zero.
Key takeaways:
- This behavior is defined by fundamental C/C++ language rules, not a special operator
- It works across different compilers because it’s based on core language specifications
- While technically valid, it’s considered poor style due to poor readability
- Clearer alternatives exist for decrementing loops
- This construct is more of a historical curiosity than a recommended practice
Understanding this oddity is valuable for recognizing and interpreting code you might encounter, but when writing your own code, prioritize clarity over cleverness. The real beauty of C/C++ lies in expressing complex ideas clearly, not in creating syntactic puzzles.