What is the "-->" operator in C++?

7 974

1 857

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

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?

GManNickG

Posted 2009-10-29T06:57:45.903

Reputation: 295 719

10@SadSido I guess your "runs to" operator 0 &lt;---- x will not work, since post/prefix increment/decrement operators do not produce the necessary lvalues. Good variants, though! – Johan Bezem – 2011-11-23T11:16:13.727

5@SadSido, the reverted "operator" doesn't work as intended, as x will never get to 0 in the loop. – Qtax – 2012-03-15T18:06:20.393

62Opens the possibility of a whole new expressive way of coding, well worth sacrificing a few compiler warnings for: bool CheckNegative(int x) { return x<0 ? true :-( false ); } – ttt – 2012-05-28T11:12:58.730

436Or even just proper spacing... I don't think I've ever seen a space between the variable and either ++ or -- before... – Matthew Scharley – 2009-10-29T07:09:47.470

13I was completely surprised too when i saw "/" and "/" operator, and was thinking what does this line "i / 100 / = N;" compute for? – Test – 2009-10-29T07:21:07.233

987This "goes to" operator can be reverted ( 0 <-- x ). And also there is a "runs to" operator ( 0 <---- x ). Geez, the funniest thing I've ever heard of c++ syntax =) +1 for the question. – SadSido – 2009-10-29T07:27:21.857

191Funnily enough, although the interpretation is very wrong, it does describe what the code does correctly. :) – Noldorin – 2009-11-11T13:51:39.640

23And the great modernizer: it works perfectly in C# (with confusing spaces)! – Darren Oster – 2009-11-12T23:56:11.833

14Oh no, be careful when using "-->" operator. RValue must be smaller than LValue otherwise you may get loop overflow :)) – instcode – 2009-12-30T08:43:10.373

11One of my annoyances with VS 2008 is that it's automatic reformatting breaks this idiom in the wrong places. – Pete Kirkham – 2010-01-13T13:47:31.323

726Imagine the new syntax possibilities: #define upto ++&lt;, #define downto --&gt;. If you're feeling evil, you can do #define for while( and #define do ) { (and #define done ;}) and write for x downto 0 do printf("%d\n", x) done Oh, the humanity... – Chris Lutz – 2010-03-04T07:07:25.283

24

Eric Lippert got a nice April Fools' Joke out of it: http://blogs.msdn.com/ericlippert/archive/2010/04/01/SomeLastMinuteFeatures.aspx

– Tim Pietzcker – 2010-04-07T07:13:02.333

11You could #define lim while and write lim(x --&gt; 0) printf("%d", x); and think of it as "the limit as x approaches zero." (though of course, on the last iteration x == 0 so it's not totally equivalent to the mathematical limit... which I guess I'm grateful for so people don't actually do this in real life). – Cornstalks – 2013-09-14T03:19:29.663

18You could also have two xa approach 0 at the same time, counting down 2x as fast. while( x --&gt; 0 &lt;-- x ) will count down in steps of 2. – Stephan Muller – 2013-10-03T19:30:12.917

3

This is often confused with -> [Structure pointer] Operator but this is where the [BODMAS][http://en.wikipedia.org/wiki/Order_of_operations] predominantly matters. For compilers ,It would be like: while( x--> 0 ) But for humans, it should be documented like : while( (x--) > 0 ) Still AI remains beyond :)

– itechnician – 2013-10-08T11:22:33.550

8That makes my stomach hurt. At first I thought I was missing some new C++11 feature. Please nobody do this--97% of people trying to read and understand your code are not going to know this trick and are going to waste time trying to figure it out. x-- > 0 is a lot more readable. Besides, int x = 0; while( x --> 10 ); does not "goes to" 10 (except after some 4 billion subtracts on a 32 bit machine). – Scott – 2013-12-08T15:36:11.720

9@StephanMuller: I believe what you propose is an undefined behavior - modifying the same variable more than once without a sequence point in between – EFraim – 2013-12-08T15:38:10.457

5@EFraim you're right, I tested the code but apparently not well, because when I try now it's giving errors. My bad. – Stephan Muller – 2013-12-09T09:19:05.663

2It should be closed to avoid continous minor changes in the top answers. I can't see the other way to achieve this. – Kirill V. Lyadvinsky – 2015-08-19T12:41:31.200

6I would like to save a line and scope x by writing for (int x = 10; x > 0; --x). – albert – 2011-02-21T05:31:19.880

1This is an urban legend at this point. I have seen it in books, magazines, online, etc. I think it even usually has a line about someone being surprised that it compiled, and is always followed by a challenge to explain it. – Synetech – 2016-04-07T20:38:11.320

@JohanBezem predec/increment do return lvalues. but i think that code might be broken for a worse reason: not at compile time due to return type, but rather at runtime with UB - due to performing multiple modifications to the same object without any sequence point in between – underscore_d – 2016-08-10T19:44:14.570

1@Scott "except after some 4 billion subtracts on a 32 bit machine", no, signed integer over or underflow is UB. – 12431234123412341234123 – 2017-09-01T10:33:13.963

This code is not C code since ANSI-C, but work on most compilers. In C, a empty parameter list is not allowed so int main() is not ANSI-C nor C99 nor C11. But K&R-C can have this. – 12431234123412341234123 – 2017-09-01T10:37:04.947

2@12431234123412341234123, UB doesn't mean it won't happen. Try int x = INT_MIN; --x; and despite being UB, see what happens practically on most platforms. It'd be challenging to find one that didn't exhibit the same behavior. But that's moot--I looked closer at it and of course (x = 0) is not > 10 so the loop body will run 0 times, not 4 billion. It wouldn't even have a chance to underflow. So that's my 'duh' moment. But my original point is: readable code is better than kitschy code. – Scott – 2017-09-05T19:14:26.477

1

@Scott: Of course it would run 0 times, and it is not that easy readable. But me point was, a underflow in signed integer (also overflows and also in floats) is UB. A Platform which can make problems with under and overflows is GCC (with -O2 or higher) on x86 and AMD64 (one of the most used platform), see also this question https://stackoverflow.com/questions/7682477/why-does-integer-overflow-on-x86-with-gcc-cause-an-infinite-loop

– 12431234123412341234123 – 2017-09-06T10:00:25.063

sigh So much discussion over a parenthetical statement. Perhaps I should have added "possibly" or "usually" or "even though it's not defined behavior..". – Scott – 2017-09-06T18:55:47.320

@albert, thank you. Is it just me who thinks that there's something seriously wrong with you if you choose something this unreadable over a for loop? – Ayberk Özgür – 2017-10-18T13:36:52.103

3Interestingly it still executes ten times, that could be why the original in the book was put together like that, to show that if you were simply counting down that it could conceivably be more interesting to use that particular syntax. – davidahines – 2011-09-13T15:04:56.503

1I don't understand why this question got so much attention. It's just a standard question related to operator priority and just a bit confusing for newbies due to uncommon placing of space character. But that's all. – tangoal – 2018-08-10T21:04:40.053

Answers

7 670

Pay attention

--> is not an operator. It is in fact two separate operators, -- and >.

The conditional's code 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)

Charles Salvia

Posted 2009-10-29T06:57:45.903

Reputation: 41 753

213Then again, it does kind of look like some kind of range operator in that context. – Charles Salvia – 2009-10-29T07:14:52.067

89Saying 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 – 2009-10-29T08:35:27.600

I think first compare then decrement --x>0 first decrement then compare – Sajad Bahmani – 2009-11-18T12:54:07.140

30In Java it also compiles :) – Steven Devijver – 2013-02-12T08:07:27.103

3I 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 – 2010-01-30T17:42:40.673

4while(i--) {...} – dimpiax – 2013-04-30T07:51:42.777

1Note that when you exit the while loop, x will contain -1, not 0. This is because the loop breaks when the current value is 0 or less and this is then decremented. Additionally, you are approaching 0 from "above" so you will reach 0, decrement and break. If x begins below 0, it will simply decrement and never enter the loop. – aring – 2013-11-19T16:48:14.507

the first thing that came in my mind was "what? is this some fancy c++ syntactic sugar thing to express ptr** ", but than there was the 0 behind it ... – zhengtonic – 2014-03-13T13:28:56.400

2The notation --> is often used by the more mathematical purist programmers, I have even heard it termed as "tends to" as that is effectively the behaviour it is being used for in many cases. In regards to --) that's the vertical biclops smiley.... ;D or predecrement banana, whichever you prefer :D – GMasucci – 2014-05-23T13:42:13.120

3IMHO "to better understand, the statement could be as follows:" while (x &gt; 0) { x--; printf("%d ", x); } or even better: a for loop. – August Karlstrom – 2014-07-02T12:18:29.323

@sellibitze and knittl, not to even mention the fact that post 3 address code generation optimization is still possible and store/loads may be moved around in any order as long as it doesnt change the observable behavior, by one thread. And this is true at compiler level, and CPU level as well (OOO). So while your correction is true at the virtual C++ machine level, its false in practice. – v.oddou – 2014-09-01T03:38:10.933

1The &gt; 0 is not needed since the while loop will stop at x=0 – Andy_A̷n̷d̷y̷ – 2015-11-01T09:39:54.073

That's interesting that it isn't an operator, but is there a name for it? Or do we just have to call it the arrow thingy? – Jay Schauer – 2015-12-26T21:36:59.140

28The name for it, @Jay, is bad programming style :-) This is evidenced by the fact the question was asked in the first place. It makes much more sense to textually bind operators to the thing they're operating on rather than something unrelated, so while (x-- &gt; 0) would be more apt. It also makes it more obvious what's going on (at least in a fixed-font editor) meaning that the parentheses in this answer would not be necessary. – paxdiablo – 2016-02-15T01:28:00.940

2Note that I'm not saying you have to leave out spaces between operators and operands (like a+b) just that they shouldn't give unbalanced preference (a+ b or a +b) or incorrect preference (as in the question, or char* x, y (that's a char pointer and a char so would be better written as char *x, y or `char y, *x) to avoid possible confusion). – paxdiablo – 2016-02-15T01:30:54.193

12So to explain the "-->" operator you have to use the "( (" operator and the "--) >" operator? – Ira Baxter – 2016-04-02T20:37:40.197

int x = 0; int y = 10; do{ printf("%d", -x); }while(-y <-- x);

Less good since you need to negate the value of x and y, but it does result into an increasing range operator – Rik Schaaf – 2016-05-23T04:23:54.390

@knittl I don't think there support for your claim in the standard. The standard only says that x-- means to decrease the value of x while the value of the expression is the original value of x. – skyking – 2016-06-27T11:08:20.360

1@AugustKarlstrom You are wrong cause in case of x == 0 while (x &gt; 0) {x--;} gives you x == 0 but while (x--&gt;0){} gives you x == -1 – tyger – 2016-07-23T15:52:38.817

1@tyger You're right, and this illustrates how error prone expressions with side-effects are. – August Karlstrom – 2016-07-24T13:02:57.587

For a moment I thought it was about "->" . What is the name of this operator? – android developer – 2016-08-14T16:41:58.793

@androiddeveloper The one in the question has no standard name, the one in your comment is called the dereference (or indirection) operator. – Thomas – 2016-08-16T11:02:34.683

I would say that a "name" for this would be "greedy parser". C++ keeps grabbing characters from the stream as long as it results in something it understands. That's why this comes out as -- and >, as opposed to - and ->. – cvanbrederode – 2017-01-23T21:06:55.513

Also works in PHP, you cannot speed it up with a double -- unfortunately as it gives a parse error. – visualex – 2017-03-21T08:03:24.437

It's actually a useful feature: an easier way to create a countdown loop (shorter than for) – Vladislav Toncharov – 2018-04-08T15:46:29.380

2 508

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...

unsynchronized

Posted 2009-10-29T06:57:45.903

Reputation: 3 922

37Sorry, I don't get this one. How does this work? – mafu – 2012-03-07T10:48:26.567

166@mafutrct - As I remember it \ in C just appends the next line as if there was not a line break. The \s here basically do nothing. – Hogan – 2012-03-10T04:37:36.063

2@mafu the '\' character tells the compiler that the current line continues in the next line and so the compiler should merge both lines and compile as one. 'while (x -- > 0)' will run until x is equals to -1. But, the way he makes the indentations makes it look like x is sliding to zero. 'While x slides to 0...' – Felype – 2013-05-20T18:10:06.837

8IIRC, K&R C allowed whitespace between the '-'s in the decrement operator, in which case you could have the backslashes in the middle of it, which would look even cooler. :) – Jules – 2013-07-13T09:23:17.810

1A backslash is an escape character, you are escaping the newlines using \<enter> so that the only thing the compiler sees is white space which is essentially removed, so this is equivalent to (x -- > 0) – GL2014 – 2016-08-12T19:05:24.320

1

@ArnavBorborah https://en.wiktionary.org/wiki/a_picture_paints_a_thousand_words

– unsynchronized – 2016-09-10T02:52:27.833

@unsynchronized but where is the 'words' – Arnav Borborah – 2016-09-10T10:28:42.520

8@ArnavBorborah it's an old expression meaning why waste words when a picture does a better job , used as a joke in this context. (there are in fact 2 keywords while and printf ) – unsynchronized – 2016-09-10T11:36:46.297

23Ah yes, the obscure slide operator. How could I forget! – demonkoryu – 2017-10-27T10:00:48.173

@unsynchronized: printf is not a keyword in C.

– Fred Larson – 2018-04-30T14:41:10.373

@Hogan backslash "\" doesn't tell compiler to append next line in the current one. It just escapes line ending \n. – totten – 2018-05-29T09:28:09.457

1@totten -- I guess you have a point - in fact no "appending" will happen -- it will just be ignored by the lexer and parser. Of course, from an abstract and end user point of view it is the same as an appending. But you make an excellent point about it not being the "same thing." – Hogan – 2018-05-31T16:23:33.733

+1 for (Monty) Python reference, ...and now for something completely different... a smooth operator with a sliding nose (the sliding nose is the rough operator maybe?) – Will Croxford – 2018-07-30T11:26:33.490

2 252

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.

Kirill V. Lyadvinsky

Posted 2009-10-29T06:57:45.903

Reputation: 76 879

1 170

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
}

Jay Riggs

Posted 2009-10-29T06:57:45.903

Reputation: 46 170

117While this might help many to understand the code, a few lines to explain it properly would be helpful. – Dukeling – 2015-05-22T12:57:26.917

1This is not quite right. The value of x inside the loop body is different in the second case. The assignment statement in your example should be above the logic for it to be equivalent. Postfix -- subtracts 1, but the comparison will happen with the value from before the subtraction. – uliwitness – 2018-10-16T16:03:48.877

925

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

;)

doc

Posted 2009-10-29T06:57:45.903

Reputation: 4 818

3which operating system, this type of output generated, i am using a ubuntu 12.04 in that i had a error message – Bhuvanesh – 2015-01-19T12:13:36.457

1

@Bhuvanesh operating system is irrelevant. This is simple C++ code (using printf(), because OP uses it), which should compile everywhere, so it must be your error. http://coliru.stacked-crooked.com/a/f5fdc710da0398c9

– doc – 2015-01-19T13:03:53.480

49Though it should be obvious, to everyone new to C++ reading this: don't do it. Just use augmented assignment if you have need to increment/decrement by more than one. – Blimeo – 2015-03-26T02:41:40.853

181Zero with "lasers". while( 0 > - - - - - -- -- -- -- -- ---------- x ) ... same output. – Samuel Danielson – 2016-03-09T21:54:16.553

1Nice try, but --x does not return an lvalue, so --(--x) does not compile. – phord – 2016-03-23T16:45:06.793

2

@phord are you sure it does not compile? --> http://coliru.stacked-crooked.com/a/5aa89a65e3a86c98

– doc – 2016-03-24T10:43:16.603

9@doc It compiles in c++, but not in c. – phord – 2016-03-25T14:58:46.247

2I've just checked that, both opposite goes to operator and the laser BIU~~ operator are just not so fast, cuz they can't be optimized by gcc! – Xiè Jìléi – 2016-05-30T01:38:26.770

2

Yeah, this doesn't compile in C.

– MD XF – 2017-02-21T16:15:58.303

509

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 make the things look funny, -- decrements and > compares.

RageZ

Posted 2009-10-29T06:57:45.903

Reputation: 21 191

377

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

Posted 2009-10-29T06:57:45.903

Reputation: 54 829

433Not 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 – 2009-12-30T05:16:46.543

19Well, 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 – 2010-04-12T15:07:58.783

8@burrito Although I don't disagree, loops conditioned on non-zero values generally get predicted near perfectly. – Duncan – 2014-01-11T09:05:12.060

4@Konerak Going from an O(N) operation to an O(1) one is almost always preferable. – Alice – 2014-03-25T04:26:53.493

The C increment/decrement operators gave access to PDP11 instructions. On that arch p++ was faster than ++p, and --p than p--. I can't remember if p++, p-- & ++p, --p, differed in cycle times but there were micro-optimisations available to those who coded carefully. The reason, was the arch was tuned to support the very common stack operations, push & pop. – Rob11311 – 2014-05-29T13:04:46.457

9Increment and decrement are equally fast, probably on all platforms (definitely on x86). The difference is in testing the loop end condition. To see if the counter has reached zero is practically free - when you decrement a value, a zero flag is set in processor and to detect the end condition you just need to check that flag whereas when you increment a comparison operation is required before end condition can be detected. – lego – 2015-02-18T11:14:01.093

6Of course, all this is moot these days, since modern compilers can vectorize and reverse loops automatically. – Lambda Fairy – 2015-02-20T03:53:56.197

This would be better as a footnote in another answer or a comment - it clearly doesn't explain what --&gt; means, which is what was asked. – Dukeling – 2015-05-22T12:55:22.397

IIRC the PDP11 *p++ was the basis for the FORTH implementation and part of it's great speed (compiled code being 'faster' than regular assembler, and it didn't need to access or use a call instruction ;-) – Philip Oakley – 2015-06-23T16:14:55.010

6In x86 ASM, the LOOP &lt;address&gt; decreases the ECX register, then jumps to &lt;address&gt; 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 --&gt; 0 loop if the value of counter isn't used in the loop. – Mark K Cowan – 2015-07-08T11:26:58.503

3Continuing my previous comment: MOV ECX, value, @start:, &lt;code&gt;, LOOP @start is an x86 ASM equivalent for counter = value - 1; while (counter --&gt; 0) { &lt;code&gt;; }. Note that it will barf if value is initially zero, so an extra check is needed pre-loop. – Mark K Cowan – 2015-07-08T11:32:17.677

327

while( x-- > 0 )

is how that's parsed.

Grumdrig

Posted 2009-10-29T06:57:45.903

Reputation: 10 681

303

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

Escualo

Posted 2009-10-29T06:57:45.903

Reputation: 25 160

277I hope I never come across any of your source code… – mk12 – 2012-08-15T01:44:31.287

49@Mk12 That's not source code...it's hieroglyphics :-) – raffian – 2012-09-07T03:27:35.067

14

@SAFX - It would be perfectly hieroglyphics with egyptian brackets

– mouviciel – 2012-11-14T10:00:02.100

This doesn't compile. C is not Pascal, where the interior of do ... while is a statement list. In C it is a block, so it must be do { ... } while. – user207421 – 2016-09-11T02:20:23.950

15@EJP it does compile. The syntax is do statement while ( expression ) ;. Having said that, I hope it is understood I meant the example as a joke. – Escualo – 2016-10-18T17:28:10.427

287

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 ^^

NguyenDat

Posted 2009-10-29T06:57:45.903

Reputation: 3 348

93Your 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. – Tim Leaf – 2010-05-05T15:26:03.457

20Additionally, x and -- are two separate tokens. – Roland Illig – 2010-07-02T19:20:05.843

14

This is known as Maximal munch.

– RJFalconer – 2014-03-13T11:09:26.933

20@DoctorT: it passes the lexer. only semantic pass is capable of emmiting that error. so his explanation is correct. – v.oddou – 2014-09-01T03:34:53.157

8As long as you think --&gt; is an operator (which is what's implied by having the question that was asked), this answer isn't helpful at all - you'll think token 2 is --&gt;, not just --. If you know that --&gt; isn't an operator, you probably don't have a problem understanding the code in the question, so, unless you have a completely different question, I'm not really sure how this could be useful. – Dukeling – 2015-05-22T12:33:43.607

4

@DoctorT example can be correct assuming that a has overloaded post-decrement operator, which returns lvalue. http://coliru.stacked-crooked.com/a/e1effc351ae79e9f

– doc – 2015-07-08T11:20:12.867

2It explains why it doesn't get parsed to a - -&gt; b since -&gt; is an operator itself. – Buge – 2016-01-08T01:41:16.000

Actually (x-)-> would be a syntax error. – BJovke – 2016-11-26T10:37:28.460

Tried a-----b and the compiler says Expression is not assignable, even when using c++11. – Hola Soy Edu Feliz Navidad – 2018-08-29T14:02:25.657

244

This is exactly the same as

while (x--)
{
   printf("%d ", x);
}

for non-negative numbers

Good Person

Posted 2009-10-29T06:57:45.903

Reputation: 1 097

130Shouldn't this be for(--x++;--x;++x--)? – Mateen Ulhaq – 2011-12-04T21:32:19.380

7@DoctorT that's what unsigned is for – Cole Johnson – 2013-03-23T18:39:13.253

11@MateenUlhaq, that is wrong according to the standard the expression --x++ has undefined behaviour according to §1.9.15 – WorldSEnder – 2015-06-19T02:02:01.700

221

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.

Test

Posted 2009-10-29T06:57:45.903

Reputation: 1 603

13Goes to cant be true always especially when value of x is negative. – Ganesh Gopalasubramanian – 2009-11-13T03:22:41.113

3I think this is a little bit misleading... We don't have a literally "goes to" operator, since we need another ++&gt; to do the incremental work. – tslmy – 2013-06-15T02:49:10.983

17@Josh: actually, overflow gives undefined behavior for int, so it could just as easily eat your dog as take x to zero if it starts out negative. – SamB – 2013-12-06T06:57:56.927

14The other version does not do the same thing - with for (size_t x=10; x--&gt;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 – 2010-06-21T08:57:44.143

2This is a very important idiom to me for the reason given in the comnmet by @PeteKirkham, as I often need to do decreasing loops over unsigned quantities all the way to 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 --&gt; without space, as this makes the idiom easy to recognise. – Marc van Leeuwen – 2014-08-30T20:08:39.370

... Actually, I somewhat regret that writing while(0&lt;--n) does not do the same thing as writing while(n--&gt;0), and the former is usually not what you want. On the other hand, at least in C++, you can make it descend twice as fast with while(0&lt;----n). – Marc van Leeuwen – 2014-08-30T20:16:12.283

1x=10; while(x --&gt; 0) is not the same as for(x=10; x&gt;0; x--)... it would on the other hand be the same as for(x=10-1; x=&gt;0; x--) . – Horse SMith – 2014-11-21T02:12:47.313

1Well, also while(0 &lt;=-- x). But this's getting silly(er) :p – Noein – 2015-05-26T07:57:21.300

203

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

Sajad Bahmani

Posted 2009-10-29T06:57:45.903

Reputation: 11 642

157

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.

cool_me5000

Posted 2009-10-29T06:57:45.903

Reputation: 1 795

4The 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. – Tim Leaf – 2010-05-05T15:30:19.063

10while( x-- &gt; 0 ) actually means while( x &gt; 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. – Dukeling – 2015-05-22T12:28:30.970

129

There is a space missing between -- and >. x is post decremented, that is, decremented after checking the condition x>0 ?.

Mr. X

Posted 2009-10-29T06:57:45.903

Reputation:

35The space is not missing - C(++) ignores whitespace. – None – 2012-08-02T19:16:31.373

23@H2CO3 This isn't true in general. There are places where white space must be used to separate tokens, e.g. in #define foo() versus #define foo (). – Jens – 2013-04-25T21:16:44.457

27@Jens How about: "The space is not missing - C(++) ignores unnecessary white space."? – Kevin P. Rice – 2013-12-04T20:35:14.183

121

-- is the decrement operator and > is the greater-than operator.

The two operators are applied as a single one like -->.

sam

Posted 2009-10-29T06:57:45.903

Reputation: 346

7They're applied as the 2 separate operators they are. They're only written misleadingly to look like "a single one". – underscore_d – 2016-11-12T17:56:09.313

114

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            

Rajeev Das

Posted 2009-10-29T06:57:45.903

Reputation: 791

109

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

AndroidLearner

Posted 2009-10-29T06:57:45.903

Reputation: 892

4Except that ++> can hardly be used in a while(). A "goes up to..." operator would be ++<, which doesn't look anywhere as nice. The operator --> is a happy coincidence. – Florian F – 2014-09-01T09:46:25.247

Could while (0 &lt;-- x) also work, then? – Ben Leggiero – 2015-06-15T14:00:33.930

1

@BenLeggiero That could 'work' in the sense of generating code that does something (while infuriating readers who don't like faux-clever code), but the semantics are different, as its use of predecrement means it will execute one fewer iteration. As a contrived example, it would never execute the loop body if x started at 1, but while ( (x--) &gt; 0 ) would. {edit} Eric Lippert covered both in his C# 4 release notes: https://blogs.msdn.microsoft.com/ericlippert/2010/04/01/some-last-minute-new-c-4-0-features/

– underscore_d – 2016-11-12T17:57:29.713

102

C and C++ obey the "maximum 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 an valid expression.

Pandrei

Posted 2009-10-29T06:57:45.903

Reputation: 3 907

5Which is what the OP assumed: that "((a)-->)" was the maximal munch. It turns out that the OP's original assumption was incorrect: "-->" is not a maximum valid operator. – david – 2014-08-28T00:41:45.467

4Also known as greedy parsing, if I recall correctly. – Roy Tinker – 2015-07-11T01:04:15.210

1@RoyTinker Greedy scanning. The parser has nothing to do with this. – user207421 – 2016-09-11T02:21:50.067

24

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

Does the same thing. 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's too much people making simple things complicated nowadays ;)

Garry_G

Posted 2009-10-29T06:57:45.903

Reputation: 89

20

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 e.g:

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){
        // Code
        a = a -1 // Decrement inside loop
    }
}

both ways, we do the same thing and achieve the same goals.

Zohaib Ejaz

Posted 2009-10-29T06:57:45.903

Reputation: 283