An amusing piece of code

Gregory Smith greg at utcsri.UUCP
Wed Apr 9 05:20:38 AEST 1986


In article <1370 at ism780c.UUCP> tim at ism780c.UUCP (Tim Smith) writes:
>Here is an amusing piece of code that someone who wants to remain
>annonymous invented.
>
>The situation is that we have something that, if written with if-then-else
>would be
>
>	if ( thing == A )
>		A-code;
>	else
>	if ( thing == B || thing == C || thing == D ) {
>		switch ( thing ) {
>	case B:         B-code; break;
>	case C:         C-code; break;
>	case D:         D-code; break;
>		}
>		BCD-common-code;
>	} else
>	if ( thing == E )
>		E-code;
>
>A, B, C, D, and E are constant expressions, so this is not elegant.
>We would like to use a switch for everything.  Here is a solution:
>
>	switch ( thing ) {
>case A:         A-code; break;
>case B:         B-code; if ( 0 ) {
>case C:         C-code; if ( 0 ) {
>case D:         D-code; }}
>		BCD-common-code; break;
>case E:         E-code;
>	}
>
>Noone here has been able to come up with a reasonable style for this.  The
>example above is not to bad, but if B-code, C-code, etc, are complicated,
>then it starts to get ugly.
>
Many points for creative use of if-statements... do you know about the
obfuscated C contest..? :-)

My $0.02:

	switch ( thing ) {
case A:         A-code; break;
case B:         B-code; BCD_common();	break;
case C:         C-code; BCD_common();	break;
case D:         D-code; BCD_common();	break;
case E:         E-code;
	}
...
BCD_common(){
	BCD-common-code;
}

The function call is very cheap if it has no parameters. I have done the
above many times.

If you must do nasty things, at least be honest about it:

	switch ( thing ) {
case A:         A-code; break;
case B:         B-code; goto BCD;
case C:         C-code; goto BCD;
case D:         D-code; 
	BCD:	BCD-common-code; break;
case E:         E-code;
	}

Despite the fact that this contains 2 more ( pardon my language )
`goto's I feel it is much clearer than the example using castrated
`if's, which after all are just `goto's in disguise. At least *real*
`goto's are easily recognizable as such. There is another thing you can
do, but only if the switch is to be followed by a return:

	switch ( thing ) {
case A:         A-code; return;		/* skip BCD-common */
case B:         B-code; break;		/* do BCD-common */
case C:         C-code; break;
case D:         D-code; break;
case E:         E-code; return;
	}
	BCD-common-code;
}	/* end of function */

This may look a little iffy but I would rank it above the goto solution
in clarity. I think it is less clear than the function call, and probably
less maintainable, but it would be faster. I have also done this one many
times.

-- 
"If you aren't making any mistakes, you aren't doing anything".
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg



More information about the Comp.lang.c mailing list