GOTO controversy 
Author Message
 GOTO controversy





        >>>Although some people feel that the GOTO statement/structure in programming is
        >>>terrible (hard-to-follow spaghetti code), I think it is a necessary component
        >>>of any language.  It is the most versatile looping structure (can be adapted
        >>>to pre-test, post-test conditions with an IF, can take you anywhere) and is
        >>>closest to machine language.  
        >>>I am trying to get a feel for how people feel about the GOTO statement...
        >>>please post..

        >>One place I find GOTOs lead to cleaner code is when there are several
        >>places where I want to skip to some later point if some condition or
        >>logical function is true.  Using if statements for this purpose leads to
        >>deep nesting and "if"s and "else"s that are separated by long distances.

        >Here is an actual example of a situation in which the code is
        >considerably worse if GOTOs are not used.  The additional time
        >spent in the "structured" code is significant; branching is
        >almost as common as arithmentic operations.

        >The code consists of two blocks.  A somewhat improved structured
        >setup is, with a little liberty with syntax;

        >block1: setup
        >{
        >    g = ...
        >    switch(g)

        >1:  .....

        >2:  i=1; exit;

        >3,5,6,9,10,11:      break;

        >4:  i=2; exit;

        >7:  i=3; g4=1; exit;

        >8:  code which computes i=3 or 4, and computes g4; exit;

        >default: code which can compute an i>4, some other things, and
        >    exit, or which can bresk;

        >}

        >block2:    
        >{
        >    switch(i)

        >1:  exit;

        >2:  ....; exit;

        >3:  ....; exit;

        >4:  g = ...;
        >    if(g > g4){...; i=2; break}
        >    else{....; if(BIT)exit; i=3; break}

        >5:  g = ...;
        >    ....
        >    if(BIT)
        >    {if(...)i=2; exit;}
        >    {g4 = ...; if(..) {i=3; break}
        >    i=4; break}

        >default:  code which does something and produces a smaller i;
        >}

        >fin:

        >Now the better GOTO code.  First, observe that in block2, no
        >i<6 is needed except as a location.  The other thing is based
        >on the combination of setup and code, and special cases.

        >block1: small setup;
        >{
        >start:      g = ...
        >    switch(g)

        >1:  .....:

        >2:  m = 0; goto fin;

        >3,5,6,9,10,11:      break;

        >4:  m = ...; goto fin;

        >7:  m = ....; goto fin;

        >8:  setup;
        >    g4 = ... ; if(...)goto c3; goto c4;

        >default: .....;
        >    if(..) break;
        >    setup;
        >    code which can goto c5, or compute an i>5 and goto ch, or break;
        >}

        >block2:    

        >ch: code which goes to either ch with reduced i, or one of the
        >    other c's;

        >c5: g = ...;
        >    ....:
        >    if(BIT)
        >    {if(...) goto c2; goto fin}
        >    {g4 = ...; if(..) goto c3}
        >c4: g = ...;
        >    if(g > g4){...; ....; goto fin;}
        >    else{....; if(BIT)goto fin; ...;}
        >c3: ....;
        >c2: ....;
        >c1:

        >fin:

        >This code has far fewer branches.  Each invocation of the state
        >machine in the structured code involved an extra branch.  In the
        >most common cases, parts of the setup are avoided.  

        >But there are 5 different exits from block1.  And in block2, all of
        >the common states are only known from the position of the instruction
        >counter; the state number is only stored when it is high.  Also,
        >block2 is "open"; it does not have to be set off as a block.  
        >The only reason in this code that block1 has to be set off is
        >that break is used.  If instead there was a goto leading to start:
        >instead of break, this would not be needed.

        >BTW, there are other possible versions of block1 with the same
        >bersion of block2.

        >This code is at least as easy for a human to understand as the
        >original, and if compilers cannot figure out how to optimize it,
        >we do not know how to make optimizing compilers.
        >--
        >Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907-1399

---A clearer rendition in PL/I is far easier to follow:

block1:
        select (g);
                when (1) . . .
                when (2) do; i = 1; return; end;
                when (3,5,6,9,10,11) ;
                when (4) do; i = 2; return; end;
                when (7) do; i = 3; g4=1; return; end;
                when (8) . . .
                otherwise . . .
        end;

block2:
        select (i);
                when (1) return;
                when (2) do; ... return; end;
                when (3) do; ... return; end;
                when (4) do; g = ...; if g>g4 then do; ... i=2; end;
                                      else do; ... if (bit) then return; i = 3; end;
                when (5) case5: do;
                                   g = ...
                                   if BIT THEN do; if (..) then do; i = 2; leave case 5; end;
                                   g4 = ... if ( ) then do; i = 3; leave case5; end;
                                   i = 4;
                                end;
                otherwise . . .
        end;



Wed, 12 Aug 1998 03:00:00 GMT  
 GOTO controversy


                        ..................

Quote:
>    >Here is an actual example of a situation in which the code is
>    >considerably worse if GOTOs are not used.  The additional time
>    >spent in the "structured" code is significant; branching is
>    >almost as common as arithmentic operations.
>    >Now the better GOTO code.  First, observe that in block2, no
>    >i<6 is needed except as a location.  The other thing is based
>    >on the combination of setup and code, and special cases.

My alternative code is deleted for brevity.  I wil also take the liberty
to correct a few omissions. and I will point out the gains of the use
of goto's where they occur.  I may possibly butcher the PL/I syntax somewhat,
and I have some questions about what was intended in a few places.

Quote:
>---A clearer rendition in PL/I is far easier to follow:

Is "return" supposed to exit from the block?  Where return; end; is used,
this is what should happen.  Also, in block2, this should happen when both
return and return; end; are used.  From the posted code, I am assuming that
end; without return will go to the current section, which is select in block2,
and the IRP in block1.

Quote:
>block1:     setup;

IRP
        g = G();

Quote:
>    select (g);
>            when (1) . . .; end;                    *
>            when (2) do; i = 1; return; end;
>            when (3,5,6,9,10,11) ; end;
>            when (4) do; i = 2; return; end;        *
>            when (7) do; i = 3; g4=1; return; end;
>            when (8) . . .
>            otherwise . . .
>    end;
>block2:
>    select (i);
>            when (1) return;
>            when (2) do; ... return; end;
>            when (3) do; ... return; end;
                                 i=2;                   *
>            when (4) do; g = ...; if g>g4 then do; ... i=2; end;
>                                  else do; ... if (bit) then return; i = 3; end;
>            when (5) case5: do;
>                               g = ...
>                               if BIT THEN do; if (..) then do; i = 2; leave case 5; end;
>                               g4 = ... if ( ) then do; i = 3; leave case5; end;
>                               i = 4;
>                            end;
>            otherwise . . .
>    end;

Let us consider block2 first, as it can be used with other versions of block1.
With the improved code, the value of i is known only by the program counter.

Now i=1 is a dropthrough to the next part of the code, which is a loop in
which this all occurs.  If we make (2) last, there is no cost of return, but
merely a dropthrough.  (3) drops through to (2).  The i=2 part of (4) is done
by adding some code and exiting.  Also, dropping through when it takes the
3 exit minimizes branching.  The case i=5 is handled as stated, except that
the new value if i is not stored and the select made, but a simple goto
is used.  The rare "otherwise" is the only place where the value of i is
even explicitly available in a register.

As this code is spending more time in control than in arithmetic, this
difference is important.

Now this would require that block1 have six exits, one for each case
in the structural select of block2.  But much of the setup code can be
dispensed with if some code can be inserted for cases 2, 4, and 7 in
block 1, althogh the full setup is rarely introduced unnecessarily.

These three cases bypass block2 completely.  The instruction to store
the value if i is only used when it exceeds 5, which is rare.  The
revised block1 needs to exit to the finish (cases 2, 4, and 7), the
cases corresponding to i=3 and i=4 (case 8), and to i=5 or otherwise
(the otherwise in block1 when it exits that block).
--
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907-1399



Wed, 12 Aug 1998 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. GOTO controversy

2. GOTO controversy

3. GOTO controversy

4. To GOTO or not GOTO

5. Topspeed File Driver (Continuing Controversy)

6. Case sensitivity variable controversy

7. Floating Point Controversy?

8. THEN controversy

9. Visual C++ controversy

10. High-level languages, large projects, GNOME and the .NET controversy

11. Module Packages - package-search-strategy controversy

12. Linda controversy

 

 
Powered by phpBB® Forum Software