Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives to `while (1)` to simplify branching [duplicate]

Tags:

c

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?

like image 623
Philippe A. Avatar asked Aug 05 '14 17:08

Philippe A.


2 Answers

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"

like image 153
ouah Avatar answered Nov 05 '22 10:11

ouah


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); 
like image 41
Fiddling Bits Avatar answered Nov 05 '22 11:11

Fiddling Bits