views:

47802

answers:

21

After reading this post on comp.lang.c++.moderated, I was completely surprised that it compiled and worked in both VS 2008 and G++ 4.4. The code:

#include <stdio.h>
int main()
{
     int x = 10;
     while( x --> 0 ) // x goes to 0
     {
       printf("%d ", x);
     }

} 

Where in the standard is this defined, and where did it come from?

I'd assume C, since it works in GCC as well, but I put C++ on there just in case C++ has more to mention on it. On a more subjective note, I've never heard of this before, had anybody else? Is it worth using?

Edit

Because people keep taking this the wrong way, yes, I knew the answer and merely thought it would be a fun question. :P Kirill was the first to call me out, after I left a few "egging on" comments.

You sillies.

+433  A: 

That's not an operator -->. That's two separate operators, -- and > You're post decrementing x and then comparing x and 0 with the > operator

Charles Salvia
Bah, I freakin feel tricked. In my defense Derek called it an operator and I abandoned all caution. :(
GMan
Ha! I must give this to my students on the next exam!
Thomas Padron-McCarthy
Not to offend or anything, but I was somewhat surprised that someone with 10.6K rep would ask this
Charles Salvia
Then again, it does kind of look like some kind of range operator in that context.
Charles Salvia
I agree, I should have seen it. Though these are all just excuses, it's probably the combination of me being tired and seeing it on comp.lang.c++ (automatic "trust" in words), not to mention the alarm of another poster.
GMan
this answer is only partly right: the variable x is post decremented AFTER being compared to 0
knittl
Saying that x is post-decremented and then compared to 0 is the same as saying x is decremented after being compared to 0
Charles Salvia
@knittl: Your comment isn't any better. The return value of the subexpression "x--" is defined to be the old value. When the actual decrement is happening doesn't matter because you are not allowed to access x once more before the next sequence point. In case x is an object of a user-defined type, the postfix decrement will be a function call which is supposed to decrement the object and return a copy of the previous value. Since there are two sequence points (entering and leaving the function) involved, the decrement would come before the comparison in that case (user-defined types).
sellibitze
"comp.lang.c++ (automatic "trust" in words)" I can't remember the last time I trusted anything said on a usenet group. :-)
Nosredna
I think first compare then decrement --x>0 first decrement then compare
SjB
@Thomas Padron-McCarthy: Seriously, giving such a question on an exam should never be done. What you do is tell your students that theese kind of obfuscating of the code is only going to make your students confused, and some of them might actually write this kind of code in real life. I'm really irritated at my professors for writing ugly, obfuscated code, and testing us with code which deserves death penalty.
martiert
If you're going to put it on an exam, make it a bonus question.
Kyralessa
Thomas sounds evil.
At some point people should start realizing that their (correct) answer already exists, and there's no need to replicate it.
Daniel Daranas
oh spoiled it ... still, a good "puzzler" on the syntax.
Michael Neale
I don't think it's the same. I think the word "then" implies there is an order (after post decrementing, x's value is one less). I think one can say "You're post decrementing x and then comparing its old value and 0 ..." to make it clearer. But this is nitpicking anyway. We all know what is meant.
Johannes Schaub - litb
+156  A: 

I think it's equivalent to:

while( x-- > 0 )
Jay Riggs
+1 Here comes your nice answer badge.
Amarghosh
99... one more point to a pretty gold badge.
Myrddin Emrys
+35  A: 

It's

#include <stdio.h>
int main()
{
     int x = 10;
     while( x-- > 0 ) // x goes to 0
     {
       printf("%d ", x);
     }

}

Just the space make the things look funny, -- decrements and > compare.

RageZ
+30  A: 
while( x-- > 0 )

is how that's parsed.

Grumdrig
+319  A: 

That's a very complicated operator, so C++ Standard committee even placed its description in two different parts of Standard. You could read about it in 5.2.6/2 and 5.9 in C++03 Standard.

Kirill V. Lyadvinsky
Ah, I see it now! :O!
GMan
lol! thats really very comlpicated :D
Rakesh Juyal
This comment made me smile at the end of a day's work!
Oxymoron
It's an oxymoron =)
Johannes Schaub - litb
@litb, "Search my questions and answers" link in your profile doesn't work.
Kirill V. Lyadvinsky
@Kirill, oh thanks! What a coincident, i already removed it, but SO came back at me telling me my new nick "Johannes Schaub (litb)" is invalid, and the silly link came back without me noticing :) Fixed it now.
Johannes Schaub - litb
You, sir, win the subtle answer of the century award.
Randolpho
Why is this answer not the one, that is accepted? :) Say no to boring answers!
shylent
Agreed: subtle answer of the century :-)
chester
+7  A: 

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.

EffoStaff Effo
Goes to cant be true always especially when value of x is negative.
Ganesh Gopalasubramanian
It will get there eventually.
jleedev
The other version does not do the same thing - with `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.
Pete Kirkham
+12  A: 

That is great, you could also do x++<10 which would grow till it hit 10, but isn't nearly as sneaky.

I am not sure what we could call ++< It looks like it should be some emotion icon.

RobKohr
++< is the equally-rare, "launch missile," operator.
Andres Jaan Tack
That, to me, looks like a pope hat.
James
I love how @Andres' comment has over 6 times as many upvotes as the answer it comments on.
Chris Lutz
+18  A: 

Equally confusing is the rises to operator:

while( x ++< 100 )

(Edit: Fixed error caused by Murphy's law.)

Sindri Traustason
That is backwards. Either the loop will immediately exit because x is below 100 or the loop will continue forever with a value of x about 100. It should be x ++< 100.
Dean Putney
"forever" is a strong word. Eventually it would wrap to negative/zero and end the loop.
James
@James: Not necessarily. In C++, the compiler is permitted (but not required) To assume that overflow can not occur, and thus may optimize the clause to `for(;;x++)` in order to skip the comparison
TokenMacGuy
+5  A: 

Also:

(x-->0)  (x--<0)  (--x>0) 
(--x<0)
(x++>0)
(x++<0)
(++x>0) 
(++x<0)

Also, mix these expressions with the = operator, like this: (x--=>). This is really nice.

Loai Najati
+19  A: 

As a side note, the opposite of the --> operator

while (x --> 0)

i.e. the <-- operator

while (0 <-- x)

also works, though in a slightly different manner

ammoQ
for some strange reasons the real opposite operator is "<=--" :P
quinmars
Otherwise known as 'firework'.
Pete Kirkham
quinmars, your "<=-- operator" is broken if x is unsigned. :-)
R..
+13  A: 
   #include <stdio.h>

   int main() {
         int x = 10;
         int y = ???;
         int z = ???;
         while( x -->> y -->> z )
         {
           printf("%d ", x);
         } 
    }

outputs:

9 8 7

What is the value of y and z?

Eddy Pronk
Is there an answer really? y seems negative but no number fits.
ns
y=2 and z=1. On the 4th iteration y is -1 which just returns a 0 when right shifting so it doesn't loop any further.
Android
+7  A: 

Such syntax trick was used early in C and widely used in present time. Look here, for instance (sqlite3 in the list).

big-z
+10  A: 

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.

Matt Joiner
Not exactly true. Decrementing and Incrementing take the same amount of time, the benefit of this is that comparison to zero is very fast compared to comparison versus a variable.This is true for many architectures, not just x86. Anything with a JZ instruction (jump if zero).Poking around you can find many "for" loops that are written backwards to save cycles on the compare. This is particularly fast on x86 as the act of decrementing the variable set the zero flag appropriately, so you could then branch without having to explicitly compare the variable.
burito
@burito: thx for the clarification
Matt Joiner
Compare CPU time that was saved with this technique and brain time wasted in this SO question. Which is bigger?
Tadeusz A. Kadłubowski
Well, decrementing toward zero means you only have to compare against 0 per loop iteration, while iterating toward n means comparing with n each iteration. The former tends to be easier (and on some architectures, is automatically tested after every data register operation).
Joey Adams
+4  A: 

This code first compare x and 0 then decrement x . [ also say in 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 know first compare and then decrement by see 0 in output .

if we want to first decrement and then compare use this code :

#include <stdio.h>
int main()
{
     int x = 10;
     while( --x> 0 ) // x goes to 0
     {
       printf("%d ", x);
     }

}

that output is :

9 8 7 6 5 4 3 2 1
SjB
+5  A: 

there is a space missing between -- and > .. x is post decremented ie decremented after checking the condition X>0 ?

You've bumped a very old and answered question :/
GMan
...and still got 6 damn points for it X(
Tamás Szelei
+7  A: 

This is exactly the same as

while (x--)
Good Person
Depends on the initial value of x
Artelius
This is true... it requires x to be positive. Still cool though! +1 :)
DoctorT
+2  A: 

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;
}

could be written to do the same thing.

It is nice that it looks like while x goes to 0 though.

cool_me5000
What are you quoting?
nobar
The result is only undefined when you're incrementing/decrementing the same variable more than once in the same statement. It doesn't apply to this situation.
DoctorT
+1  A: 

cool_me5000: "The result is undefined when a variable is referenced within an expression that increments or decrements it" There is nothing wrong with the code above, well, except that it looks funny. If what your are saying was true, they'd be no need in having both i++ and ++i in the language. You are probably thinking about the case such as a[i++] = i++ which really is problematic.

ivar
+1  A: 

-- is decrement operator and '>' greater then operator, is two operators applied as a single one like -->

sam
+3  A: 

in one book i read before they said ( i don't remember correctly what is book ): Compiler try to parse expression to bigest token by using left right rule: In this case is:

x-->0

Parse to bigest token:

token 1: x--
token 1: >
token 2: 0
conclude: x-- > 0

Same as:

a-----b

After parse

token 1: a--
token 2: -
token 3: --b
conclude: a-- - --b

Hope it help to understand complicate expression ^^

nguyendat
Your second explanation is not correct. The compiler will see `a-----b` and think `(a--)-- - b`, which does not compile because `a--` does not return an lvalue.
DoctorT
Additionally, `x` and `--` are two separate tokens.
Roland Illig
+2  A: 

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;
}
Arrieta
Please, may I never have to maintain your code.
Donal Fellows