3 ms·
I encountered one of these beautiful things you mention not too long ago. void foo() { do { for (...) { if (...) {
by sigjuice 9y ago
I encountered one of these beautiful things you mention not too long ago.
void foo()
{
do {
for (...) {
if (...) {
break;
}
}
if (...) {
...
if (...) {
...
break;
}
}
/* even more nested loops and conditionals with break sprinkled all over */
} while (0);
...
}
PS: IMHO this code goes too far with the "goto considered harmful" philosophy. The "while (0)" is serving the purpose of a label. An explicit label instead would be more readable, IMHO.
- erikpukinskis 9y agoSmells bad, but could legitimately be the correct structure. Depends on the problem and performance constraints. If you have a lot of conditionals and it's too expensive to run them all, nested ifs are correct. If you need to break from conditions arising from a multiple indexes, then nested loops are correct. Dogma has no place in coding. Best practices give you a sense of smell. They don't tell you how to factor.
- openasocket 9y agoYou would never use nested if statements for performance reasons. The conditions in any modern language will short circuit, which will give the equivalent behavior as manually making nested loops. Depending on the circumstances it might be more readable, but never more performant.
- taneq 9y agoNested if-statements lets you avoid re-evaluating the conditions between if-statements. Short-circuit evaluation only partially addresses that. It can be cleaner to cache the conditions in a few flags if you want to do it that way, though. I'm not saying deeply nested conditionals are pretty, just that there are some cases where they're quicker. (Of course, if you're scraping the bottom of the barrel for that kind of speedup then chances are, there are algorithmic improvements that will yield orders of magnitude more gains.)
- openasocket 9y agoDepending on the specifics, an alternative is to break that "while(0)" loop into a function and use "return" instead of break. Even more of an alternative (and would only be a good idea in certain circumstances) is, in a language with destructors, to make an object created at the top with a destructor for that last block of code, so you can throw out the loop and use return instead of break. This would also work with Golang defer statements. But again, only a good idea if that makes some sort of sense in your program, and isn't just a work around for the lack of gotos. Gotos make me cringe, a "while(0)" hack makes me cringe just as much. The whole problem with goto is it confuses the reader as to where the control flow is going, but this is just as bad because until you read to the end you're under the impression those statements will be run multiple times.