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. I would assume this is also valid C since it works in GCC as well.
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
Where is this defined in the standard, and where has it come from?
-->
sequence with multiple redundant answers, some serious, some funny... and an amazing score! - anyone -->
is not an operator. It is in fact two separate operators, --
and >
.
The code in the condition decrements x
, while returning x
's original (not decremented) value, and then compares the original value with 0
using the >
operator.
To better understand, the statement could be written as follows:
while( (x--) > 0 )
Answered 2023-09-20 19:53:17
x--
though it does further enforce the separation. It would probably be enough just to associate tokens more clearly with something like while (x-- > 0)
. - anyone 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...
Answered 2023-09-20 19:53:17
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.
Answered 2023-09-20 19:53:17
x
can go to zero even faster in the opposite direction in C++:
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
;)
Answered 2023-09-20 19:53:17
It's equivalent to
while (x-- > 0)
x--
(post decrement) is equivalent to x = x-1
(but returning the original value of x
), so the code transforms to:
while(x > 0) {
x = x-1;
// logic
}
x--; // The post decrement done when x <= 0
Answered 2023-09-20 19:53:17
x--
is in no way equivalent to x = x-1
. - anyone --x
is equivalent to x = x-1
and x -=1
. -1
from me. - anyone x--
is equivalent to (x = x-1) + 1
. - anyone 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.
Answered 2023-09-20 19:53:17
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.
Answered 2023-09-20 19:53:17
-->
means, which is what was asked. - anyone LOOP <address>
decreases the ECX
register, then jumps to <address>
unless the decrementing of ECX
resulted in zero. Decrementing the loop counter towards zero allows the compiler to generate a single LOOP
instruction, whereas incrementing or counting to other values requires separate INC/DEC/ADD/SUB, compare, and conditional jump instructions. Modern compilers can often convert other loops to a counter --> 0
loop if the value of counter
isn't used in the loop. - anyone MOV ECX, value
, @start:
, <code>
, LOOP @start
is an x86 ASM equivalent for counter = value - 1; while (counter --> 0) { <code>; }
. Note that it will barf if value
is initially zero, so an extra check is needed pre-loop. - anyone 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;
}
Answered 2023-09-20 19:53:17
atoi
makes the code smell immediately. - anyone 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
Answered 2023-09-20 19:53:17
This is exactly the same as
while (x--)
Answered 2023-09-20 19:53:17
unsigned
is for - anyone while (x --> 0)
is not the same as while (x--)
if x
has a signed type, the first loop does not execute at all if x
has a negative value but the second iterates many times until it hits undefined behavior when x
reaches INT_MIN
. - anyone x
is negative, UB only happens when x == INT_MIN
, at least x - INT_MIN
iterations occur before this... Conversely, if x
has an unsigned type, no undefined behavior happens for arithmetic operations: they are computed modulo 2 to the power <number of bits of the type>. - anyone 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.
Answered 2023-09-20 19:53:17
for (size_t x=10; x-->0; )
the body of the loop is executed with 9,8,..,0 whereas the other version has 10,9,..,1. It's quite tricky to exit a loop down to zero with an unsigned variable otherwise. - anyone ++>
to do the incremental work. - anyone int
, so it could just as easily eat your dog as take x
to zero if it starts out negative. - anyone 0
. (For comparison, the idiom of omitting tests for zero, such as writing while (n--)
instead for unsigned n
, buys you nothing and for me greatly hampers readability.) It also has the pleasant property that you specify one more than the initial index, which is usually what you want (e.g., for a loop over an array you specify its size). I also like -->
without space, as this makes the idiom easy to recognise. - anyone 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
Answered 2023-09-20 19:53:17
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.
Answered 2023-09-20 19:53:17
while( x-- > 0 ) actually means while( x > 0)
- I'm not sure what you were trying to say there, but the way you phrased it implies the --
has no meaning whatsoever, which is obviously very wrong. - anyone x
will be -1
after it leaves the loop, while in this answer, x
will be 0
. - anyone There is a space missing between --
and >
. x
is post decremented, that is, decremented after checking the condition x>0 ?
.
Answered 2023-09-20 19:53:17
#define foo()
versus #define foo ()
. - anyone --
is the decrement operator and >
is the greater-than operator.
The two operators are applied as a single one like -->
.
Answered 2023-09-20 19:53:17
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
Answered 2023-09-20 19:53:17
C and C++ obey the "maximal munch" rule. The same way a---b
is translated to (a--) - b
, in your case x-->0
translates to (x--)>0
.
What the rule says essentially is that going left to right, expressions are formed by taking the maximum of characters which will form a valid token.
Answered 2023-09-20 19:53:17
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
Answered 2023-09-20 19:53:17
x
started at 1, but while ( (x--) > 0 )
would. {edit} Eric Lippert covered both in his C# 4 release notes: blogs.msdn.microsoft.com/ericlippert/2010/04/01/… - anyone Instead of regular arrow operator (-->) you can use armor-piercing arrow operator: --x> (note those sharp barbs on the arrow tip). It adds +1 to armor piercing, so it finishes the loop 1 iteration faster than regular arrow operator. Try it yourself:
int x = 10;
while( --x> 0 )
printf("%d ", x);
Answered 2023-09-20 19:53:17
Extra Long Arrow
operator which moves twice as fast, x ----> 0
- anyone Extra Long Armor Piercing Arrow
operator, ----x> 0
for your fast piercing - anyone 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 ;)
Answered 2023-09-20 19:53:17
The OP's way: 9 8 7 6 5 4 3 2 1 0
and The Garry_G way: 10 9 8 7 6 5 4 3 2 1
- anyone x=x-1
before printf
then you can say "it does the same thing". - anyone x=x-1
is definitely more complicated than x--
(more characters to type, harder to read because people wonder why you're not just using good old x--
, etc.) Also, C programmers who consider things like side effects in while
to be overly complicated tend to make me suspicious. - anyone 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.
Answered 2023-09-20 19:53:17
a--
after the while shouldn't be there. - anyone a
after the loop completes is -1
in the first case and 0
in the second. - anyone (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.
Answered 2023-09-20 19:53:17
-->
is not an operator, it is the juxtaposition of --
(post-decrement) and >
(greater than comparison).
The loop will look more familiar as:
#include <stdio.h>
int main() {
int x = 10;
while (x-- > 0) { // x goes to 0
printf("%d ", x);
}
}
This loop is a classic idiom to enumerate values between 10
(the excluded upper bound) and 0
the included lower bound, useful to iterate over the elements of an array from the last to the first.
The initial value 10
is the total number of iterations (for example the length of the array), and one plus the first value used inside the loop. The 0
is the last value of x
inside the loop, hence the comment x goes to 0.
Note that the value of x
after the loop completes is -1
.
Note also that this loop will operate the same way if x
has an unsigned type such as size_t
, which is a strong advantage over the naive alternative for (i = length-1; i >= 0; i--)
.
For this reason, I am actually a fan of this surprising syntax: while (x --> 0)
. I find this idiom eye-catching and elegant, just like for (;;)
vs: while (1)
(which looks confusingly similar to while (l)
). It also works in other languages whose syntax is inspired by C: C++, Objective-C, java, javascript, C# to name a few.
Answered 2023-09-20 19:53:17
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.Answered 2023-09-20 19:53:17
--
at the end of the loop. - anyone 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.
Answered 2023-09-20 19:53:17
That's what you mean.
while((x--) > 0)
We heard in childhood,
Stop don't, Let Go (روکو مت، جانے دو)
Where a Comma makes confusion
Stop, don't let go. (روکو، مت جانے دو)
Same Happens in Programming now, a SPACE makes confusion. :D
Answered 2023-09-20 19:53:17
while((x --)> 0)
- anyone while (x --> 0)
is clear and effective. x
takes all values below the starting one down to and including 0
, which is perfect for a loop enumerating index values for an array for both signed and unsigned types of x
. - anyone The operator you use is called "decrement-and-then-test". It is defined in the C99 standard, which is the latest version of the C programming language standard. The C99 standard added a number of new operators, including the "decrement-and-then-test" operator, to the C language. Many C++ compilers have adopted these new operators as extensions to the C++ language.
Here is how the code without using the "decrement-and-then-test" operator:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x--;
}
}
In this version of the code, the while
loop uses the >
operator to test whether x
is greater than 0. The x--
statement is used to decrement x
by 1 at the end of each iteration of the loop.
Answered 2023-09-20 19:53:17
while (x-->0)
loop: the x--;
statement must be moved before the printf
statement and also inserted after the while
loop body. - anyone