🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #3494

Re: Multi-level break and elimination of GOTO

#3494
From: Lawrence Kirby
Date: Fri, 17 Nov 1995 00:22
138 lines
5126 bytes
In article <zaBqw0zpkjtb085yn@merlin.magic.mb.ca>
           wrightd@merlin.magic.mb.ca "David C. Wright" writes:

>This is a very strange argument.  Is it really that onerous to include a
>control variable that decides whether or not a given level of looping is to
>be broken out of?  I speak of a construction such as:
>
>int loop = 0;
>
>for(;;)
>{
>  loop++;
>  while(whatever)
>  {
>    loop++;
>    while(something)
>    {
>      loop++;
>      if(getout)
>      {
>        loop = 0;
>        break;
>      }
>    }
>    if(loop < 2) break;
>  }
>  if(loop < 1) break;
>}

Not onerous to write but as your example clearly(!) shows the results
can be almost unreadable. The point is to express the *algorithm* clearly
in your code. If the algorithm naturally terminates several layers of
loop on a deep condition the code should reflect that directly. Adding
tests at each loop level is pure obfuscation.

>You can construct #defines to handle variable management, and use enums to
>handle loop level labels.  All the tools are there for the price of a short
>#include file such as:
>
>/*  Filename brkloop.h */
>enum looptype_e = {0=outside, firstloop, secondloop, thirdloop};
>typedef enum looptype_e looptype;
>
>#define loopcontrol looptype _loop
>#define breakout(a) if(_loop < (a)) break
>#define newloop _loop++
>#define breakto(a) _loop = (a); break
>
>and you wind up with code such as:
>
>#include <brkloop.h>
>
>loopcontrol;
>
>for(;;)
>{
>  newloop;

This accesses _loop which is uninitialised.

>  while(whatever)
>  {
>    newloop;
>    while(something)
>    {
>      newloop;
>      if(getout)
>        breakto(outside);
>      if(gettofirstlevel)
>        breakto(firstloop);
>      else
>        breakto(secondloop);
>    }
>    breakout(secondloop);
>  }
>  breakout(firstloop);
>}

This is a) very difficult to read and b) highly dangerous since it is not
a general solution (you have to follow a lot of quirky and non-obvious
rules to make it work correctly) and could quite easily blow up in
unexpected ways. It is a good rule of thumb to never attempt to use the
preprocessor to change the language itself (which is effectively what you
are trying to do).

>Simple and straightforward.

Anything but. Anyway if you want 'simple and straightforward' you'd be
hard pushed to beat goto.

> Any more elaborate solution can be solved with
>the notorious goto command, or setjmp(), and amounts to the same thing.

One of the problems is that code evolves. You may start with something
that fits your model reasonably well. Then it changes slightly and suddenly
doesn't. You then have to rewrite it extensively.

> Is
>it not more sensible to use the language tools available to handle the job
>with minimal fuss and no extra keywords?

There's nothing wrong with keywords if they do something generally useful
and do it safely (or as safely as is possible). If the existing language
tools can handle the job then fine, but in this case they cannot.

>I use a similar #include file to
>allow the inclusion and retention of heirarchial debugging fprintf()
>statements in my programs that can be activated from the command line on
>demand to track down problems.  Sure, it increases the size of the
>executable, but it has little impact on development time or performance,
>and saves time on maintenance and debugging, which are the real time-sinks
>involved.

This is a very different issue which does not affect the basic flow of
execution in the program (if I'm wrong here you'd better explain
'heirarchical debugging fprintf() statements' in a little more detail).

>Language extensions that make tracing code more difficult make my skin
>crawl, especially when they are unnecessary.  #include files and libraries
>can be constructed to handle any task, as long as you're not too lazy to
>use the facilities at your disposal.

This makes no sense. Something that is well defined by the language and
tailored to the task makes code tracing much easier than preprocessor
hacks which don't model the problem well.

>These kinds of libraries and files
>are the work of a half-hour, on a one-shot basis, so surely the investment
>in time is insignificant.

It is just the damage to readability and maintainability you do in using
them that is disasterous.

-- 
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
Technical Details
Message-ID: <816567756snz@genesis.demon.co.uk>
Path: arc1-ca.pugleaf.net!mail2news.demon.co.uk!genesis.demon.co.uk
References: <47s7l0$r18@news.mel.aone.net.au> <815950407snz@genesis.demon.co.uk> <zaBqw0zpkjtb085yn@merlin.magic.mb.ca>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!mail2news.demon.co.uk!genesis.demon.co.uk
From: Lawrence Kirby <fred@genesis.demon.co.uk>
Newsgroups: comp.std.c,comp.lang.c
Subject: Re: Multi-level break and elimination of GOTO
Date: Fri, 17 Nov 95 00:22:36 GMT
Organization: none
Message-ID: <816567756snz@genesis.demon.co.uk>
References: <47s7l0$r18@news.mel.aone.net.au> <815950407snz@genesis.demon.co.uk> <zaBqw0zpkjtb085yn@merlin.magic.mb.ca>
Reply-To: fred@genesis.demon.co.uk
X-NNTP-Posting-Host: genesis.demon.co.uk
X-Newsreader: Demon Internet Simple News v1.27