After reading Hidden Features and Dark Corners of C++/STL on comp.lang.c++.moderated
, I was completely surprised that the following snippet compiled and worked in both Visual Studio 2008 and G++ 4.4.
Here's the code:
#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
I'd assume this is C, since it works in GCC as well. Where is this defined in the standard, and where has it come from?
This question is related to
c++
c
operators
code-formatting
standards-compliance
Actually, x
is post-decrementing and with that condition is being checked. It's not -->
, it's (x--) > 0
Note: value of x
is changed after the condition is checked, because it post-decrementing. Some similar cases can also occur, for example:
--> x-->0
++> x++>0
-->= x-->=0
++>= x++>=0
(x --> 0)
means (x-- > 0)
.
(x -->)
Output: 9 8 7 6 5 4 3 2 1 0
(-- x > 0)
It's mean (--x > 0)
Output: 9 8 7 6 5 4 3 2 1
(--\
\
x > 0)
Output: 9 8 7 6 5 4 3 2 1
(\
\
x --> 0)
Output: 9 8 7 6 5 4 3 2 1 0
(\
\
x --> 0
\
\
)
Output: 9 8 7 6 5 4 3 2 1 0
(
x
-->
0
)
Output: 9 8 7 6 5 4 3 2 1 0
Likewise, you can try lot of methods to execute this command successfully.
while( x-- > 0 )
is how that's parsed.
Or for something completely different... x
slides to 0
.
while (x --\
\
\
\
> 0)
printf("%d ", x);
Not so mathematical, but... every picture paints a thousand words...
--
is the decrement operator and >
is the greater-than operator.
The two operators are applied as a single one like -->
.
This code first compares x and 0 and then decrements x. (Also said in the first answer: You're post-decrementing x and then comparing x and 0 with the >
operator.) See the output of this code:
9 8 7 6 5 4 3 2 1 0
We now first compare and then decrement by seeing 0 in the output.
If we want to first decrement and then compare, use this code:
#include <stdio.h>
int main(void)
{
int x = 10;
while( --x> 0 ) // x goes to 0
{
printf("%d ", x);
}
return 0;
}
That output is:
9 8 7 6 5 4 3 2 1
Why all the complication?
The simple answer to the original question is just:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x = x-1;
}
}
It does the same thing. I am not saying you should do it like this, but it does the same thing and would have answered the question in one post.
The x--
is just shorthand for the above, and >
is just a normal greater-than operator
. No big mystery!
There are too many people making simple things complicated nowadays ;)
That's a very complicated operator, so even ISO/IEC JTC1 (Joint Technical Committee 1) placed its description in two different parts of the C++ Standard.
Joking aside, they are two different operators: --
and >
described respectively in §5.2.6/2 and §5.9 of the C++03 Standard.
The usage of -->
has historical relevance. Decrementing was (and still is in some cases), faster than incrementing on the x86 architecture. Using -->
suggests that x
is going to 0
, and appeals to those with mathematical backgrounds.
It's equivalent to
while (x-- > 0)
x--
(post decrement) is equivalent to x = x-1
so, the code transforms to:
while(x > 0) {
x = x-1;
// logic
}
x--; // The post decrement done when x <= 0
There is a space missing between --
and >
. x
is post decremented, that is, decremented after checking the condition x>0 ?
.
x
can go to zero even faster in the opposite direction:
int x = 10;
while( 0 <---- x )
{
printf("%d ", x);
}
8 6 4 2
You can control speed with an arrow!
int x = 100;
while( 0 <-------------------- x )
{
printf("%d ", x);
}
90 80 70 60 50 40 30 20 10
;)
This -->
is not an operator at all. We have an operator like ->
, but not like -->
. It is just a wrong interpretation of while(x-- >0)
which simply means x has the post decrement operator and this loop will run till it is greater than zero.
Another simple way of writing this code would be while(x--)
. The while loop will stop whenever it gets a false condition and here there is only one case, i.e., 0
. So it will stop when the x value is decremented to zero.
char sep = '\n' /1\
; int i = 68 /1 \
; while (i --- 1\
\
/1/1/1 /1\
/1\
/1\
/1\
/1\
/ 1\
/ 1 \
/ 1 \
/ 1 \
/1 /1 \
/1 /1 \
/1 /1 /1/1> 0) std::cout \
<<i<< sep;
For larger numbers, C++20 introduces some more advanced looping features.
First to catch i
we can build an inverse loop-de-loop and deflect it onto the std::ostream
. However, the speed of i
is implementation-defined, so we can use the new C++20 speed operator <<i<<
to speed it up. We must also catch it by building wall, if we don't, i
leaves the scope and de referencing it causes undefined behavior. To specify the separator, we can use:
std::cout \
sep
and there we have a for loop from 67 to 1.
Conventional way we define condition in while loop parenthesis"()
" and terminating condition inside the braces"{}
", but this --
& >
is a way one defines all at once.
For example:
int abc(){
int a = 5
while((a--) > 0){ // Decrement and comparison both at once
// Code
}
}
It says, decrement a
and run the loop till the time a
is greater than 0
Other way it should have been like:
int abc() {
int a = 5;
while(a > 0) {
a = a -1 // Decrement inside loop
// Code
}
}
Both ways, we do the same thing and achieve the same goals.
Utterly geek, but I will be using this:
#define as ;while
int main(int argc, char* argv[])
{
int n = atoi(argv[1]);
do printf("n is %d\n", n) as ( n --> 0);
return 0;
}
Anyway, we have a "goes to" operator now. "-->"
is easy to be remembered as a direction, and "while x goes to zero" is meaning-straight.
Furthermore, it is a little more efficient than "for (x = 10; x > 0; x --)"
on some platforms.
This is exactly the same as
while (x--)
{
printf("%d ", x);
}
for non-negative numbers
One book I read (I don't remember correctly which book) stated: Compilers try to parse expressions to the biggest token by using the left right rule.
In this case, the expression:
x-->0
Parses to biggest tokens:
token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0
The same rule applies to this expression:
a-----b
After parse:
token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b
I hope this helps to understand the complicated expression ^^
It's a combination of two operators. First --
is for decrementing the value, and >
is for checking whether the value is greater than the right-hand operand.
#include<stdio.h>
int main()
{
int x = 10;
while (x-- > 0)
printf("%d ",x);
return 0;
}
The output will be:
9 8 7 6 5 4 3 2 1 0
Here --
is the unary post decrement operator.
while (x-- > 0) // x goes to 0
{
printf("%d ", x);
}
(x > 0) // 10 > 0
x-- // x = 9
x=1
, so the condition is true. As per the unary operator, the value changed to x = 0
at the time of print.x = 0
, which evaluates the condition (x > 0 )
as false and the while loop exits.It's
#include <stdio.h>
int main(void) {
int x = 10;
while (x-- > 0) { // x goes to 0
printf("%d ", x);
}
return 0;
}
Just the space makes the things look funny, --
decrements and >
compares.
My compiler will print out 9876543210 when I run this code.
#include <iostream>
int main()
{
int x = 10;
while( x --> 0 ) // x goes to 0
{
std::cout << x;
}
}
As expected. The while( x-- > 0 )
actually means while( x > 0)
. The x--
post decrements x
.
while( x > 0 )
{
x--;
std::cout << x;
}
is a different way of writing the same thing.
It is nice that the original looks like "while x goes to 0" though.
Source: Stackoverflow.com