[net.lang.c] Good code for sometimes shared case

aglew@ccvaxa.UUCP (04/14/86)

>/* Written  1:18 pm  Apr  8, 1986 by chandros@topaz.RUTGERS.EDU */
>David Linn suggests the following as a solution to the "shared code in a
>switch some of the time" problem. (I removed the goto version
>for the benefit of the younger readers.  Shame, shame, shame on you.  
>Evil gotos, gasp, and in C no less, what will the world think of next. )
>
>You forgot your structured programming rules.  What about a (here it comes
>folks) a BOOLEAN variable called do_bcd_stuff??  Also, you could
>set do_bcd_stuff to be true in the declaration, and only change it in the
>case E to be false.  Anyway, that's unimportant.  I don't ken enough 

Gasp! No! And I bet you don't like break statements too:

   for(;;) {
       S1;
       if( C1 ) break;
       S2;
       if( C2 ) break;
       S3;
       if( C3 ) break;
       S4;
   }

instead you should nest ifs

   int break_flag = 0
   
   do {
       S1;
       if( C1 ) {
	   break_flag = 1;
       }
       else {
	   S2;
	   if( C2 ) {
	       break_flag = 1;
	   }
	   else {
	       S3
	       if( C3 ) {
		   break_flag = 1;
	       }
	       else {
		   S4;
	       }
	   }
       }
   } while( !break_flag )

Or, you'll accept that. Then how about breaking out of two nested loops? 

----

It's not worth arguing about this. Proponents of gotoless programming will
with proponents of structured programming until SDI lets one through.

I will, however, take serious exception to your statement
>					       Also, you could
>set do_bcd_stuff to be true in the declaration, and only change it in the
Variables should be declared and set as close as possible to where they
are used. Unfortunately, C's syntax for declarations is a bit {awkward}
- one of the better features of C++ is that you can declare things anywhere
you want, before they're used.

Otherwise, you set yourself up for errors in maintaining the code. Say you
have
       int flag = 0;
       ...
       CASE-USING-FLAG;
       if( flag ) do-special-stuff;
and then later you decide to put the case into a loop. It can be very easy
to forget to move the declaration and setting inside the loop; and if the
case that sets the flag is infrequently used, you might not test for the
bug.
       int flag = 0;

       for(;;) {
	   CASE-USING-FLAG;
	   if( flag ) do-special-stuff;
       }
Setting the flag explicitly in each case, or setting it just before the case,
reduces the chance of this error.

----

Structured programming != Gotoless programming

Andy "Krazy" Glew. Gould CSD-Urbana.    USEnet:  ihnp4!uiucdcs!ccvaxa!aglew
1101 E. University, Urbana, IL 61801    ARPAnet: aglew@gswd-vms

greg@utcsri.UUCP (Gregory Smith) (04/21/86)

In article <2600045@ccvaxa> aglew@ccvaxa.UUCP writes:

>Structured programming != Gotoless programming

Right on.
What was really ironic about the original posting ( using if(0){...} )
was that it was obviously an attempt to avoid those satanic g*t*'s, and
therefore wind up with structured code. However, the structure of the
if's was twisted around the structure of the switch statement, so the
result was worse (less structured) than being honest and using goto's.
That was made possible by the lax rules applied to 'case' labels in C
(as opposed to, say, Pascal).
It was, in a way, analogous to
	while con1 ... if con2 ... end_while .. end_if
Which could be made to work as a 'while' with a 'break' if compilers
would allow it. I am not, of course, saying that they should. How about
producing a warning if a case label is not *directly* inside the {}'s
of the switch?
-- 
"If you aren't making any mistakes, you aren't doing anything".
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg