标签云

微信群

扫码加入我们

WeChat QR Code

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?


Or even just proper spacing... I don't think I've ever seen a space between the variable and either ++ or -- before...

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Funnily enough, although the interpretation is very wrong, it does describe what the code does correctly. :)

2019年06月26日44分55秒

Imagine the new syntax possibilities: #define upto ++<, #define downto -->. 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...

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Then again, it does kind of look like some kind of range operator in that context.

2019年06月26日44分55秒

Saying that x is post-decremented and then compared to 0 is the same as saying x is decremented after being compared to 0

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

In Java it also compiles :)

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Sorry, I don't get this one. How does this work?

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

IIRC, 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. :)

2019年06月26日44分55秒

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 )

2019年06月26日44分55秒

Ah yes, the obscure slide operator. How could I forget!

2019年06月26日44分55秒

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

2019年06月26日44分55秒

uliwitness These are truly equivalent. It would be wrong if prefix were being used: 0 >-- x In this case x is decremented prior to the logic. In postfix, the logic is executed prior to the decrement and thus both samples are equivalent. Feel free to write them up in a Console and test them.

2019年06月26日44分55秒

They're still not equivalent. After the first loop, x is -1 (or overflown in case it is unsigned), after the second, it is 0. (Assuming that x starts out non-negative, neither loop modifies x or breaks or…)

2019年06月26日44分55秒

which operating system, this type of output generated, i am using a ubuntu 12.04 in that i had a error message

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Zero with "lasers". while( 0 > - - - - - -- -- -- -- -- ---------- x ) ... same output.

2019年06月26日44分55秒

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

2019年06月26日44分55秒

doc It compiles in c++, but not in c.

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

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

2019年06月25日44分55秒

burrito Although I don't disagree, loops conditioned on non-zero values generally get predicted near perfectly.

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Of course, all this is moot these days, since modern compilers can vectorize and reverse loops automatically.

2019年06月26日44分55秒

I hope I never come across any of your source code…

2019年06月26日44分55秒

Mk12 That's not source code...it's hieroglyphics :-)

1970年01月01日00分02秒

SAFX - It would be perfectly hieroglyphics with egyptian brackets

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

Additionally, x and -- are two separate tokens.

2019年06月26日44分55秒

This is known as Maximal munch.

2019年06月26日44分55秒

DoctorT: it passes the lexer. only semantic pass is capable of emmiting that error. so his explanation is correct.

2019年06月26日44分55秒

As long as you think --> 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 -->, not just --. If you know that --> 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.

2019年06月25日44分55秒

Shouldn't this be for(--x++;--x;++x--)?

2019年06月26日44分55秒

DoctorT that's what unsigned is for

2019年06月26日44分55秒

MateenUlhaq, that is wrong according to the standard the expression --x++ has undefined behaviour according to §1.9.15

2019年06月26日44分55秒

If it were using unsigned, it would have used %u

2019年06月26日44分55秒

Goes to cant be true always especially when value of x is negative.

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

I think this is a little bit misleading... We don't have a literally "goes to" operator, since we need another ++> to do the incremental work.

2019年06月26日44分55秒

Josh: actually, overflow gives undefined behavior for int, so it could just as easily eat your dog as take x to zero if itstarts out negative.

2019年06月26日44分55秒

This 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 --> without space, as this makes the idiom easy to recognise.

2019年06月26日44分55秒

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.

2019年06月26日44分55秒

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.

2019年06月25日44分55秒

The space is not missing - C(++) ignores whitespace.

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Jens How about: "The space is not missing - C(++) ignores unnecessary white space."?

2019年06月26日44分55秒

They're applied as the 2 separate operators they are. They're only written misleadingly to look like "a single one".

2019年06月26日44分55秒

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

2019年06月26日44分55秒

Could while (0 <-- x) also work, then?

2019年06月25日44分55秒

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--) > 0 ) would. {edit} Eric Lippert covered both in his C# 4 release notes: blogs.msdn.microsoft.com/ericlippert/2010/04/01/…

2019年06月25日44分55秒

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

2019年06月26日44分55秒

Also known as greedy parsing, if I recall correctly.

2019年06月26日44分55秒

RoyTinker Greedy scanning. The parser has nothing to do with this.

2019年06月26日44分55秒

This question is not about complications, but about ** Hidden Features and Dark Corners of C++/STL**

2019年06月26日44分55秒

The program here gives different output than original because x here is decremented after printf. That demonstrates well how "simpleanswers" are usually Incorrect.

2019年06月26日44分55秒

The OP's way:9876543210 and The Garry_G way:10987654321

2019年06月26日44分55秒

It doesn't do the same thing. Move your x=x-1 before printf then you can say "it does the same thing".

2019年06月26日44分55秒

This is incorrect. The code in the question does: 'test-write-execute' (test first, write new value, execute the loop), your example is 'test-execute-write'.

2019年06月26日44分55秒

v010dya Fixed the answer, now it's test-write-execute as in the question, thanks for pointing out!

2019年06月26日44分55秒

VladislavToncharov Your edit was still wrong. See mine.

2019年06月26日44分55秒