55

Disclaimer: I know perfectly well the semantics of prefix and postfix increment. So please don't explain to me how they work.

Reading questions on stack overflow, I cannot help but notice that programmers get confused by the postfix increment operator over and over and over again. From this the following question arises: is there any use case where postfix increment provides a real benefit in terms of code quality?

Let me clarify my question with an example. Here is a super-terse implementation of strcpy:

while (*dst++ = *src++);

But that's not exactly the most self-documenting code in my book (and it produces two annoying warnings on sane compilers). So what's wrong with the following alternative?

while (*dst = *src)
{
    ++src;
    ++dst;
}

We can then get rid of the confusing assignment in the condition and get completely warning-free code:

while (*src != '\0')
{
    *dst = *src;
    ++src;
    ++dst;
}
*dst = '\0';

(Yes I know, src and dst will have different ending values in these alternative solutions, but since strcpy immediately returns after the loop, it does not matter in this case.)

It seems the purpose of postfix increment is to make code as terse as possible. I simply fail to see how this is something we should strive for. If this was originally about performance, is it still relevant today?

migrated from stackoverflow.com Feb 3 '11 at 10:03

This question came from our site for professional and enthusiast programmers.

  • 7
    The postfix variant is the most commonly used one, so if you're going to make a case against it, it better be a pretty strong case. And your first example is a bit of a straw man, since I suspect few people would actually code the strcpy method this way (for reasons you have already mentioned). – Robert Harvey Feb 1 '11 at 0:01
  • 4
    Why have either at all? – James McNellis Feb 1 '11 at 0:01
  • 31
    If we removed everything from the language that had the potential to confuse programmers, we wouldn't have very many features. The fact something isn't useful to you, or only very rarely useful, doesn't mean it should be snipped. If it's not relevant anymore, don't use it; the end. – Cody Gray Feb 1 '11 at 0:01
  • 4
    Yeah but then you can never do int c = 0; c++; – Biff MaGriff Feb 1 '11 at 0:06
  • 4
    @Cody: Because some things are both confusing and useful. He isn't confused by post-increment itself, he's confused about it's usefulness. We shouldn't have things that are useless, confusing or not. – GManNickG Feb 1 '11 at 0:34

15 Answers 15

23

While it did once have some performance implications, I think the real reason is for expressing your intent cleanly. The real question is whether something while (*d++=*s++); expresses intent clearly or not. IMO, it does, and I find the alternatives you offer less clear -- but that may (easily) be a result of having spent decades becoming accustomed to how things are done. Having learned C from K&R (because there were almost no other books on C at the time) probably helps too.

To an extent, it's true that terseness was valued to a much greater degree in older code. Personally, I think this was largely a good thing -- understanding a few lines of code is usually fairly trivial; what's difficult is understanding large chunks of code. Tests and studies have shown repeatedly, that fitting all the code on screen at once is a major factor in understanding the code. As screens expand, this seems to remain true, so keeping code (reasonably) terse remains valuable.

Of course it's possible to go overboard, but I don't think this is. Specifically, I think it's going overboard when understanding a single line of code becomes extremely difficult or time consuming -- specifically, when understanding fewer lines of code consumes more effort than understanding more lines. That's frequent in Lisp and APL, but doesn't seem (at least to me) to be the case here.

I'm less concerned about compiler warnings -- it's my experience that many compilers emit utterly ridiculous warnings on a fairly regular basis. While I certainly think people should understand their code (and any warnings it might produce), decent code that happens to trigger a warning in some compiler is not necessarily wrong. Admittedly, beginners don't always know what they can safely ignore, but we don't stay beginners forever, and don't need to code like we are either.

  • 12
    +1 for pointing out that the terse version is easier to read to some of us. :-) – R.. Feb 1 '11 at 0:56
  • 1
    If you don't like some of your compiler warnings (and there are more than a few I could do without - seriously, I meant to type if(x = y), I swear!) you should adjust your compiler's warnings options so you don't accidentally miss the warnings you do like. – Chris Lutz Feb 1 '11 at 2:09
  • 4
    @Brooks Moses: I'm a lot less enthused about that. I don't like polluting my code to make up for the compiler's shortcomings. – Jerry Coffin Feb 1 '11 at 2:23
  • 1
    @Jerry, @Chris: This annotation is intended for the case where you think the warning is usually a good thing, but you don't want it to apply to a particular line that's doing something unusual. If you never want the warning and consider it a shortcoming, use -Wno-X, but if you only want to make one exception to it and want the warning to apply everywhere else, this is much more comprehensible than using arcane hoop-jumping such as Chris refers to. – Brooks Moses Feb 1 '11 at 2:50
  • 1
    @Brooks: the double parentheses and the (void)x to silence unused warnings are fairly well known idioms to silence otherwise useful warnings. The annotation looks a bit like pragmas, not portable at best :/ – Matthieu M. Feb 1 '11 at 7:28
32

It is, err, was, a hardware thing


Interesting that you would notice. Postfix increment is probably there for a number of perfectly good reasons, but like many things in C, it's popularity can be traced to the origin of the language.

Although C was developed on a variety of early and underpowered machines, C and Unix first hit the relative big-time with the memory-managed models of the PDP-11. These were relatively important computers in their day and Unix was by far better -- exponentially better -- than the other 7 crummy operating systems available for the -11.

And, it so happens, that on the PDP-11,

*--p

and

*p++

...were implemented in hardware as addressing modes. (Also *p, but no other combination.) On those early machines, all less than 0.001 GHz, saving an instruction or two in a loop must almost have been a wait-a-second or wait-a-minute or go-out-for-lunch difference. This doesn't precisely speak to postincrement specifically, but a loop with pointer postincrement could have been a lot better than indexing back then.

As a consequence, the design patterns because C idioms which became C mental macros.

It's something like declaring variables right after a { ... not since C89 was current has this been a requirement, but it's now a code pattern.

Update: Obviously, the main reason *p++ is in the language is because it is exactly what one so often wants to do. The popularity of the code pattern was reinforced by popular hardware which came along and matched the already-existing pattern of a language designed slightly before the arrival of the PDP-11.

These days it makes no difference which pattern you use, or if you use indexing, and we usually program at a higher level anyway, but it must have mattered a lot on those 0.001GHz machines, and using anything other than *--x or *x++ would have meant you didn't "get" the PDP-11, and you would might have people coming up to you and saying "did you know that..." :-) :-)

  • 25
    Wikipedia says: "A (false) folk myth is that the instruction set architecture of the PDP-11 influenced the idiomatic use of the C programming language. The PDP-11's increment and decrement addressing modes correspond to the −−i and i++ constructs in C. If i and j were both register variables, an expression such as *(−−i) = *(j++) could be compiled to a single machine instruction. [...] Dennis Ritchie unambiguously contradicts this folk myth. [The Development of the C Language]" – fredoverflow Feb 1 '11 at 0:20
  • 3
    Huh (From the link provided in FredOverflow's comment): "People often guess that they were created to use the auto-increment and auto-decrement address modes provided by the DEC PDP-11 on which C and Unix first became popular. This is historically impossible, since there was no PDP-11 when B was developed. The PDP-7, however, did have a few `auto-increment' memory cells, with the property that an indirect memory reference through them incremented the cell. This feature probably suggested such operators to Thompson; the generalization to make them both prefix and postfix was his own." – Kit Scuzz Feb 1 '11 at 0:28
  • 3
    DMR only said that the PDP-11 was not the reason it was added to C. I said that too. What I said was that it was used to advantage on the PDP-11 and became a popular design pattern for that exact reason. If Wikipedia contradicts that then they are simply wrong, but I don't read it that way. It is phrased poorly on that W page. – DigitalRoss Feb 1 '11 at 0:30
  • 3
    @FredOverflow. I think you misunderstood exactly what the "folk myth" is. The myth is that C was designed to exploit those 11 ops, not that they don't exist and not that the code pattern didn't become popular because everyone knew they mapped to the 11 well. In case it isn't clear: the PDP-11 really really does implement those two modes in hardware for almost every instruction as an addressing mode, and it really was the first important machine C ran on. – DigitalRoss Feb 1 '11 at 0:32
  • 2
    "it must have mattered a lot on those 0.001GHz machines". Um, I hate to say it because it dates me, but I had Motorola and Intel manuals for my CPUs to look up the size of the instructions and how many cycles they took. Finding the smallest codes added up to being able to add one more feature to a print spooler and saving a couple cycles meant a serial port could keep up with some protocol like that newly invented MIDI. C relieved some of the nit-picking, especially as the compilers improved, but still it was important knowing what was the most efficient way to write code. – the Tin Man Feb 1 '11 at 6:57
14

The prefix and postfix -- and ++ operators were introduced in the B language (C's predecessor) by Ken Thompson -- and no, they were not inspired by the PDP-11, which didn't exist at the time.

Quoting from "The Development of the C Language" by Dennis Ritchie:

Thompson went a step further by inventing the ++ and -- operators, which increment or decrement; their prefix or postfix position determines whether the alteration occurs before or after noting the value of the operand. They were not in the earliest versions of B, but appeared along the way. People often guess that they were created to use the auto-increment and auto-decrement address modes provided by the DEC PDP-11 on which C and Unix first became popular. This is historically impossible, since there was no PDP-11 when B was developed. The PDP-7, however, did have a few ‘auto-increment’ memory cells, with the property that an indirect memory reference through them incremented the cell. This feature probably suggested such operators to Thompson; the generalization to make them both prefix and postfix was his own. Indeed, the auto-increment cells were not used directly in implementation of the operators, and a stronger motivation for the innovation was probably his observation that the translation of ++x was smaller than that of x=x+1.

  • 8
    No, I'm not related to Ken Thompson. – Keith Thompson Sep 24 '16 at 0:54
  • Thanks for this very interesting reference ! This confirms my quote from original K&R that suggested the goal of compactness rather than a technical optimization. I didn't know however that these operators already existed in B. – Christophe Sep 24 '16 at 17:30
  • @BenPen As far as I know there's no policy of closing questions if there's a duplicate on a different SE site, as long as both questions fit their respective sites. – Ordous Sep 26 '16 at 14:27
  • Interesting... The Programmer one is not as close a question certainly. – BenPen Sep 26 '16 at 14:33
  • @BenPen: The accepted answer to the Stack Overflow question already cites the same source I did (though not quite as much of it). – Keith Thompson Sep 26 '16 at 15:16
6

The obvious reason for the postincrement operator to exist is so that you don't have to write expressions like (++x,x-1) or (x+=1,x-1) all over the place or uselessly separate trivial statements with easy-to-understand side effects out into multiple statements. Here are some examples:

while (*s) x+=*s++-'0';

if (x) *s++='.';

Whenever reading or writing a string in the forward direction, postincrement, and not preincrement, is almost always the natural operation. I've almost never encountered real-world uses for preincrement, and the only major use I've found for predecrement is converting numbers to strings (because human writing systems write numbers backwards).

Edit: Actually it wouldn't be quite so ugly; instead of (++x,x-1) you could of course use ++x-1 or (x+=1)-1. Still x++ is more readable.

  • You have to be careful about those expressions since you are modifying and reading a variable between two sequence points. The order in which those expressions are evaluated is not guaranteed. – user22815 Aug 7 '14 at 21:36
  • @Snowman: Which one? I see no such issues in my answer. – R.. Aug 7 '14 at 21:42
  • if you have something like (++x,x-1) (function call, maybe?) – user22815 Aug 7 '14 at 21:46
  • @Snowman: That's not a function call. It's the C comma operator, which is a sequence point, parenthesized to control precedence. The result is the same as x++ in most cases (one exception: x is an unsigned type with rank lower than int and the initial value of x is the max value of that type). – R.. Aug 7 '14 at 22:02
  • Ah, the tricky comma operator... when a comma is not a comma. The parenthesis and rarity of the comma operator threw me off. Nevermind! – user22815 Aug 7 '14 at 22:03
4

The PDP-11 offered post-increment and pre-decrement operations in the instruction set. Now these weren't instructions. They were instruction modifiers that allowed you to specify that you wanted the value of a register before it was incremented or after it was decremented.

Here is a word-copy step in the machine language:

movw (r1)++,(r2)++

which moved a word from one location to another, pointed at by registers, and the registers would be ready to do it again.

As C was built on and for the PDP-11, a lot of useful concepts found their way into C. C was intended to be a useful replacement for assembler language. Pre-increment and post-decrement were added for symmetry.

  • That's brilliant modifiers... It makes me want to learn PDP-11 assembly. BTW, do you have a reference on "for symmetry?" It makes sense, but this is history, sometimes making sense wasn't the key. LOL – BenPen Sep 23 '16 at 21:16
  • 2
    Also known as addressing modes. The PDP-11 provided post-increment and pre-decrement which paired nicely together for stack operations. – Erik Eidt Sep 23 '16 at 21:40
  • 1
    The PDP-8 provided a post-increment memory indirection, but no corresponding pre-decrement operation. With magnetic core memory, reading a memory word wiped it out(!), so the processor used a write-back function to restore the word just read. Applying an increment before write back came about rather naturally, and a more efficient block move became possible. – Erik Eidt Sep 23 '16 at 21:54
  • 3
    Sorry, the PDP-11 didn't inspire these operators. It didn't exist yet when Ken Thompson invented them. See my answer. – Keith Thompson Sep 24 '16 at 0:54
3

I doubt it was ever really necessary. As far as I know, it doesn't compile into anything more compact on most platforms than using the pre-increment as you did, in the loop. It was just that at the time it was made, terseness of code was more important than clarity of code.

That isn't to say that clarity of code isn't (or wasn't) important, but when you were typing in on a low baud modem (anything where you measure in baud is slow) where every keystroke had to make it to the mainframe and then get echoed back one byte at a time with a single bit used as parity check, you didn't want to have to type much.

This is sort of like the & and | operator having lower precedence than ==

It was designed with the best intentions (a non-short circuiting version of && and ||), but now it confuses programmers everyday, and it probably won't ever change.

Anyway, this is only an answer in that I think there is not a good answer to your question, but I'll probably be proven wrong by a more guru coder than I.

--EDIT--

I should note that I find having both incredibly useful, I'm just pointing out that it won't change whether anyone like it or not.

  • This isn't even remotely true. At no point was "terseness of code" more important than clarity. – Cody Gray Feb 1 '11 at 0:10
  • Well, I would argue that it was much more of a point of focus. You're quite right though, it's certainly never been more important than clarity of code... to most people. – Kit Scuzz Feb 1 '11 at 0:13
  • 6
    Well, the definition of "terse" is "smoothly elegant: polished" or "using few words: devoid of superfluity," both of which are generally a good thing when writing code. "Terse" doesn't mean "obscure, hard to read, and obfuscated" like many people think. – James McNellis Feb 1 '11 at 0:21
  • @James: While you're correct, I think most people mean the second definition of "terse" when using it in a programming context: "using few words; devoid of superfluity". Under that definition, it's certainly easier to imagine situations where there is a trade-off between the brevity and expressiveness of a particular piece of code. Obviously the right thing to do when writing code is the same thing as when speaking: make things as short as they need to be, but no shorter. Valuing terseness over expressivity can lead to obfuscated-looking code, but it certainly shouldn't. – Cody Gray Feb 1 '11 at 0:41
  • 1
    rewind 40 years and imagine you had to fit your program on that drum that will hold only around 1000 characters, or write a compiler can only work with 4 thousand bytes of ram. There were times where terseness vs clarity was not even an issue. You had to be terse, there didn't exist a computer on this planet that could store, run or compile your non-terse program. – nos Feb 5 '11 at 1:38
3

I like the postfix aperator when dealing with pointers (whether or not I'm dereferencing them) because

p++

reads more naturally as "move to the next spot" than the equivalent

p += 1

which surely must confuse beginners the first time they see it used with a pointer where sizeof(*p) != 1.

Are you sure you're stating the confusion problem correctly? Is not the thing that confuses beginners the fact that the postfix ++ operator has higher precedence than the dereference * operator so that

*p++

parses as

*(p++)

and not

(*p)++

as some might expect?

(You think that's bad? See Reading C Declarations.)

2

Amongst the subtle elements of good programming are localisation and minimalism:

  • putting variables in a minimal scope of use
  • using const when write access isn't required
  • etc.

In the same spirit, x++ can be seen as a way of localising a reference to the current value of x while immediately indicating that you've - at least for now - finished with that value and want to move to the next (valid whether x is an int or a pointer or iterator). With a little imagination, you could comparable this to letting the old value/position of x go "out of scope" immediately after it's no longer needed, and moving to the new value. The precise point where that transition is possible is highlighted by the postfix ++. The implication that this is probably the final use of the "old" x can be valuable insight into the algorithm, assisting the programmer as they scan through the surrounding code. Of course, the postfix ++ may put the programmer on the lookout for uses of the new value, which may or may not be good depending on when that new value is actually needed, so it's an aspect of the "art" or "craft" of programming to determine what's more helpful in the circumstances.

While many beginners may be confused by a feature, it's worth balancing that against the long-term benefits: beginners don't stay beginners for long.

2

Wow, lots of answers not-quite-on-point (if I may be so bold), and please forgive me if I'm pointing out the obvious – particularly in light of your comment to not point out the semantics, but the obvious (from Stroustrup's perspective, I suppose) doesn't yet seem to have been posted! :)

Postfix x++ produces a temporary that's passed 'upwards' in the expression, while the the variable x is subsequently incremented.

Prefix ++x does not produce a temporary object, but increments 'x' and passes the result to the expression.

The value is convenience, for those who know the operator.

For example:

int x = 1;
foo(x++); // == foo(1)
// x == 2: true

x = 1;
foo(++x); // == foo(2)
// x == 2: true

Of course, the results of this example can be produced from other equivalent (and perhaps less oblique) code.

So why do we have the postfix operator? I guess because it's an idiom that's persisted, in spite of the confusion it obviously creates. It's a legacy construct that once was perceived to have value, though I'm not sure that perceived value was so much for performance as for convenience. That convenience hasn't been lost, but I think an appreciation of readability has increased, resulting in the questioning of the operator's purpose.

Do we need the postfix operator anymore? Likely not. Its result is confusing and creates a barrier to understandability. Some good coders will certainly immediately know where to find it useful, often in places where it has a peculiarly "PERL-esque" beauty. The cost of that beauty is readability.

I agree that explicit code has benefits over terseness, in readability, understandability and maintainability. Good designers and managers want that.

However, there's a certain beauty that some programmers recognize that encourages them to produce code with things purely for beautiful simplicity – such as the postfix operator – which code they wouldn't have otherwise ever have thought of – or found intellectually stimulating. There's a certain something to it that just makes it more beautiful, if not more desirable, in spite of pithiness.

In other words, some people find while (*dst++ = *src++); to simply be a more beautiful solution, something that takes your breath away with its simplicity, just as much as if it were a brush to canvas. That you are forced to understand the language to appreciate the beauty only adds to its magnificence.

  • 3
    +1 "some people find while (*dst++ = *src++); to simply be a more beautiful solution". Definitely. People who don't understand assembly language don't really understand how elegant C can be, but that particular code statement is a shining star. – the Tin Man Feb 1 '11 at 6:45
  • "Do we need the postfix operator anymore? Likely not." - I can't help thinking of Turing machines here. Have we ever needed automatic variables, the for statement, heck, even while (we have goto, after all)? – Bernd Jendrissek Feb 1 '11 at 19:37
  • @Bernd: Ha! Imagine closures! Closures! Scandalous! lol – Brian M. Hunt Feb 2 '11 at 2:40
  • Closures! How ridiculous. Just give me a tape! Seriously, what I meant is that I don't think /needing/ a feature should be the primary decision criterion (unless you want to design, say, lisp). IME I use (nay, need) the postfix operators almost exclusively, and only rarely need the prefix one instead. – Bernd Jendrissek Feb 2 '11 at 15:14
2

Let's look at Kernighan & Ritchie original justification (original K&R page 42 and 43):

The unusual aspects is that ++ and -- may be used either as prefix or as postfix. (...) In the context where no value is wanted (..) choose prefix or postfix according to taste. But htere are situations where one or the other is specifically called for.

The text continues with some examples that use increments within index, with the explicit goal of writing "more compact" code. So the reason behind these operators is convenience of more compact code.

The three examples given (squeeze(), getline() and strcat() ) use only postfix within expressions using indexing. The authors compare the code with a longer version that doesn't use embedded increments. This confirms that focus is on compactness.

K&R highlight on page 102, the use of these operators in combination with pointer dereferencing (eg *--p and *p--). No further example is given, but again, they make clear that the benefit is compactness.

Prefix is for example very commonly used when decrementing an index or a pointer staring from the end.

 int i=0; 
 while (i<10) 
     doit (i++);  // calls function for 0 to 9  
                  // i is 10 at this stage
 while (--i >=0) 
     doit (i);    // calls function from 9 to 0 
1

I'm going to disagree with the premise that ++p, p++, is somehow difficult to read or unclear. One means "increment p and then read p", the other means "read p and then increment p". In both cases, the operator in the code is exactly where it is in the explanation of the code, so if you know what ++ means, you know what the resulting code means.

You can create obfuscated code using any syntax, but I don't see a case here that p++/++p is inherently obfuscatory.

1

this is from the POV of an electrical engineer:

there are many processors that have built-in post-increment and pre-decrement operators for the purpose of maintaining a last-in-first-out (LIFO) stack.

it might be like:

 float stack[4096];
 int stack_pointer = 0;

 ... 

 #define push_stack(arg) stack[stack_pointer++] = arg;
 #define pop_stack(arg) arg = stack[--stack_pointer];

 ...

i dunno, but that's the reason i would expect to see both prefix and postfix increment operators.

1

To underline Christophe's point about compactness, I want to show y'all some code from V6. This is part of the original C compiler, from http://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/c/c00.c:

/*
 * Look up the identifier in symbuf in the symbol table.
 * If it hashes to the same spot as a keyword, try the keyword table
 * first.  An initial "." is ignored in the hash.
 * Return is a ptr to the symbol table entry.
 */
lookup()
{
    int ihash;
    register struct hshtab *rp;
    register char *sp, *np;

    ihash = 0;
    sp = symbuf;
    if (*sp=='.')
        sp++;
    while (sp<symbuf+ncps)
        ihash =+ *sp++;
    rp = &hshtab[ihash%hshsiz];
    if (rp->hflag&FKEYW)
        if (findkw())
            return(KEYW);
    while (*(np = rp->name)) {
        for (sp=symbuf; sp<symbuf+ncps;)
            if (*np++ != *sp++)
                goto no;
        csym = rp;
        return(NAME);
    no:
        if (++rp >= &hshtab[hshsiz])
            rp = hshtab;
    }
    if(++hshused >= hshsiz) {
        error("Symbol table overflow");
        exit(1);
    }
    rp->hclass = 0;
    rp->htype = 0;
    rp->hoffset = 0;
    rp->dimp = 0;
    rp->hflag =| xdflg;
    sp = symbuf;
    for (np=rp->name; sp<symbuf+ncps;)
        *np++ = *sp++;
    csym = rp;
    return(NAME);
}

This is code that was passed around in samizdat as an education in good style, and yet we would never write it like this today. Look at how many side effects have been packed into if and while conditions, and conversely, how both for loops don't have an increment expression because that's done in the loop body. Look at how blocks are only wrapped in braces when absolutely necessary.

Part of this was certainly manual micro-optimization of the sort that we expect the compiler to do for us today, but I would also put forward the hypothesis that when your entire interface to the computer is a single 80x25 glass tty, you want your code to be as dense as possible so you can see more of it at the same time.

(Use of global buffers for everything is probably a hangover from cutting one's teeth on assembly language.)

  • Handle with care: "ihash =+ *sp++;" At some point C had not only += but also =+ operator. Today, the =+ is an assignment operator, followed by a unary plus which doesn't do anything, so it's equivalent to "ihash = *sp; sp += 1;" – gnasher729 Sep 28 '16 at 20:23
  • @gnasher729 Yes, and later it has rp->hflag =| xdflg, which I believe will be a syntax error on a modern compiler. "At some point" is precisely V6, as it happens; the changeover to += form happend in V7. (The V6 compiler only accepted =+, if I'm reading this code correctly - see symbol() in the same file.) – zwol Sep 28 '16 at 20:58
-1

Perhaps you should think about cosmetics too.

while( i++ )

arguably "looks better" than

while( i+=1 )

For some reason, the post-increment operator looks very appealing. Its short, its sweet, and it increases everything by 1. Compare it with prefix:

while( ++i )

"looks backwards" doesn't it? You never see a plus sign FIRST in math, except when someone's being silly with specifying something's positive (+0 or something like that). We're used to seeing OBJECT + SOMETHING

Is it something to do with grading? A, A+, A++? I can tell you I was pretty cheesed at first that the Python people removed operator++ from their language!

  • 1
    Your examples don't do the same thing. i++ returns the original value of i, and i+=1 and ++i return the original value of i plus 1. Since you're using the return values for control flow, this matters. – David Thornley Dec 28 '11 at 15:23
  • Yes, you're right. But I'm looking only at readability here. – bobobobo Dec 30 '11 at 22:51
-2

Counting backwards 9 to 0 inclusive:

for (unsigned int i=10; i-- > 0;)  {
    cout << i << " ";
}

Or the equivalent while loop.

  • 1
    How about for (unsigned i = 9; i <= 9; --i)? – fredoverflow Feb 1 '11 at 18:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.