From time to time, I use a while(1)
block to flatten a succession of if..else
going out of proportion. It goes along these lines.
Instead of doing:
// process if (success) { // process if (success) { //process if (success) { // etc } } }
I do:
while (1) { // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc break; }
I am a little annoyed by the implicit jump at the end of the while
. Could I get away with a leaner construct (ie no break
at the end)?
I could trade the final break
with a variable (or register?). That's not exactly leaner or clearer.
int once = 1; while (once--) { // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc }
A for loop would look a bit better (C99):
for (int once = 1 ; once--; once) { // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc }
I thought about using a switch case. It does not look much better , though it would work.
switch (1) { default: // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc }
In that particular case the concept of a label seems unbeatable.
// process if (!success) goto end; // process if (!success) goto end; // process if (!success) goto end; // etc end:
What other approach do you guys know/use?
What other approach do you guys know/use?
You can encapsulate your while
loop in a function (and call this function where you had your while
loop):
static void process(void) { // process if (!success) return; // process if (!success) return; // process if (!success) return; // process }
Any halfway decent compiler (e.g., even gcc
with optimizations disabled) will inline a static
function if it is called once. (Of course some variables may have to be in the lexical scope of process
function, in that case just provide them as parameters of the function).
Note that writing code from top to bottom instead of horizontally (e.g., your example with nested if
) is called duffing. There is a nice article on the subject here:
"Reading Code From Top to Bottom"
Also, in the Linux kernel coding style there is a specific warning writinh against horizontal code:
"if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program"
The following is a method very similar to what you're doing with the loops, but without the need for a counter or a break
statement at the end.
do { // process if (!success) break; // process if (!success) break; // process if (!success) break; ... // No need for a break statement here } while(0);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With