| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | Merits |
Hello Bill!
Replying to a message of Bill Birrell to Darin McBride:
BB>>> Is that not a merit?
BB> No answer?
No - because you've changed topics.
>> You've also moved the increment from the while()
>> (where we've had it all along) to a new location.
BB> That came out of the original:-
Hmmm - but that wasn't the loop we were talking about.
>> However, we were intending to compare generic for()
>> and while() loops, showing how the obvious solutions
>> weren't always so obvious.
BB> You were implying that a for(;;) loop is inherently clearer than a
BB> while() loop. Without elision that is simply not true.
I really hope that I wasn't implying that. I thought I was stating it explicitly!
That's not to say I don't use while loops. Only that I get tripped up much
more often writing and reading while loops than for loops.
>> You're simply proving what
>> we've said all along: don't muck with loops without
>> really trying.
BB> Your preferences aside, Darin, you didn't answer the question. Pre
BB> and post-increments behave differently, and you cannot always use
BB> just one or the other without risking gross obfuscation.
No, but I don't think that was ever my statement, either. The claim is
that where there is no other difference (i.e., you're using the increment
purely for the side effect of the increment), then use pre-increment over
post-increment.
For the more pedantic, I would go as far as to say that you should almost
never use the increment operator when you want both the value and the
increment, such as *s++ or *++s. Split it into two statements (which is
what for() is designed to do!).
while (*s) {
putc(*s, stdout);
++s;
}
This will allow that if s is a complex object (e.g., iterator to a linked
list), you'll get the same behaviour (assuming it as the operator*
overloaded to return char), and you'll get all the performance benefit that
is possible, too.
What this habit gets for you is:
* All the same speed as your original in the trivial case (s is char*)
* Easier to read (not that *s++ is difficult, but some of us may miss the
increment operator at first glance)
* Anything easier to read is easier to maintain.
* Ability to add extra functionality after the putc more trivially.
Think of the tee command: putting the char to both stdout and a file
handle? Maybe doing a transform (from one encoding to another) on that
file handle? With the original example, we have to not only not change *s
(which we may not be allowed to do anyway if it's char const*), but
remember that the putc to stdout goes at the end. If we put new functions
in there, they must go before the increment, which, again, isn't obvious.
Splitting the increment out of the putc command makes the increment
obvious.
* Being able to swap out types (char* to iterator - even more
pathological cases can be dreamed up) and still getting as much performance
as possible. The most pathological cases are ones such as database cursors
which may be too difficult to copy, and thus post-increment isn't
available. But pre-increment is available, and this habit will get it
working with minimal fuss.
Of course, as soon as you look at all this, it should be obvious: don't use
while. Use for.
for (; *s; ++s)
{
putc(*s, stdout);
/* more stuff */
}
Easier to read, maintain, get right, get all the performance kicks ... it
simply fits the bill. I only use while when the increment operation is too
complicated to put in a for statement. Even then, I try to factor the code
so that increment is trivial (perhaps a simple function call), and then I
can put it back into a for loop. ;-)
Darin
---
* Origin: Tanktalus' Tower BBS (1:250/102)SEEN-BY: 633/267 270 @PATH: 250/102 99 10/345 106/1 2000 633/267 |
|
| SOURCE: echomail via fidonet.ozzmosis.com | |
Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.