Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site watmath.UUCP Path: utzoo!watmath!rbutterworth From: rbutterworth@watmath.UUCP (Ray Butterworth) Newsgroups: net.lang.c Subject: Re: C bites / programming style Message-ID: <16461@watmath.UUCP> Date: Mon, 16-Sep-85 10:02:41 EDT Article-I.D.: watmath.16461 Posted: Mon Sep 16 10:02:41 1985 Date-Received: Tue, 17-Sep-85 05:00:09 EDT References: <1370@brl-tgr.ARPA> <163@unitek.uucp> Organization: U of Waterloo, Ontario Lines: 80 > How about the following: > > #define cycle for(;;) { > #define endcycle } > #define then { > #define otherwise } else { > #define elseif } else if > #define endif } > #define exitwhen(exp) if (exp) break; > #define exitunless(exp) if (!(exp)) break; > > We can then write > > cycle > exitwhen(cond1) > if (cond2) then > stuff1 > elseif (cond3) then > stuff2 > otherwise > stuff3 > endif > endcycle Looks nice, but it might end up causing more problems than it solves. It has the form of an extension of the C language, but this can be misleading since the compiler doesn't really know about it. To anyone looking at the code, the "endcycle" in the last line obviously matches the "cycle" in the first. Unfor- tunately the compiler never sees these keywords, only the "{" and "}". You could just as easily have put an "endif" in place of the "endcycle" without getting any complaint from the compiler which would produce the correct code despite the mistake. What happens when you accidentaly mess up the compound if statement so that the braces don't quite match? The compiler won't complain until half way down the next page, and you won't have a clue that the "endcycle" actually matches one of the "then" keywords. And you have lost the ability to use VI's % command to tell you which "{" matches which "}". Or consider an even worse example of this type of thing which will compile and lint without error and might even execute correctly some of the time (at least enough to pass the tests before release). cycle c=getchar(); startswitch(c) default: exitwhen(++counter>LIMIT); putchar(BEEP); break; case EOF: exitwhen(ferror(stdin)); case '\n': return; case BLAT: case BLORT: etc. dosomething(); break; etc. endswitch endcycle an_error(); How obvious is it that the "exitwhen" really generates a "break" that applies to the "case" and not to the "cycle"? The use of "break" for both "case" and "for" control is a limitation built into the C language. So is the use of "}" to end the compound statements following both a "switch" and a "for". These are features that C programmers have to live with. Using #defines to make C look like "it should" doesn't solve the problem, it only hides it, making it even harder to find when it occurs. If you really want these extensions to C, then either they should be added to the compiler or a separate pre-processor should be written which knows how to match "cycle" with "endcycle" and which can issue appropriate error messages when they don't match.