[net.lang.c] What should be added to C - structured design support

rb@ccird1.UUCP (Rex Ballard) (06/07/86)

In article <1006@dataioDataio.UUCP> bright@dataio.UUCP (Walter Bright writes:
>In article <2823@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>>>> o Any sort of multi-level break statement.  There is no syntacticly clean
>>>> way of adding this to C.
>>>C already has a multi-level break statement.  It's spelled "goto."
>>>Putting a goto in a costume doesn't disguise it.
>>When a human reading a program sees 'break', it is immediately known
>>that the current loop is being abandoned. In order to determine the
>>effect of a goto, you have to find its destination. If you don't
>>believe there is a big difference, try maintaining someone else's
>>BAS*C code sometime.
>
>There's no problem finding where a goto goes to if you have only one or
>two in a function. Gotos only become a problem when you have a snarl
>of them. What I find confusing is four page functions, with 47 levels
>of ifs and {}s, and trying to figure out where control flow goes when a
>break happens. You have to count }s, or run a listing and connect the
>{}s with a pen.

ICK!!!
47 levels of ifs and {}s in the SAME FUNCTION??!!??!!

>
>I've had people do greps for gotos on my code, show me an out-of-
>context list of the 14 they found in 10,000 lines of C, and tell me
>that my code was bad.

Please don't tell me you mean 10,000 lines in the same function.

>Using only structured programming constructs only guarantees that the
>flow graph for your program will be reducible, it doesn't guarantee
>that your program is structured. The only purpose to having a reducible
>flow graph is if your optimizer can't handle irreducible ones.

Obviously, "structured programming" and "structured design" have not
yet been integrated :-).

One of the painful beauties of FORTH is that it is nearly impossible to
write one LONG function when several SHORT ones would make the who
task easier to understand.  Even without the "16 line block" editor,
it is hard to get past 10 or 15 statements without "loosing the stack".

Unfortunately, C is much more "structured", which makes it much easier
to write one function that "initializes the world" in-line.

As any good C programmer why he doesn't "break it down" a little, he'll
tell you "it would slow things down".

OK how about a nice "quick call" or "gosub", or something that would
be optimized to not do the frame saves?

Another common "trick" is to write a big huge case statement where each
case contains nearly identical code an let the "-O" option break the
whole thing into hundreds of little "subroutines and jumps".

The most common use for "gotos" is a "switch inside a loop which needs
to execute the common code on two or more conditions".

The examples usually look so trivial that the solutions appear obvious
to everyone.  The someone point out that the example is a simplification
of some monster program.

Of course, if you have "hundreds of little functions" running around,
you now need a associative database to keep track of what the cryptic
names really mean and who calls who, right?

The solution involves not just the Compiler, but the Assembler/Linker too.
By using "real" names instead of "glyphs" and having the
Compiler/Assembler/Linker produce a "system data-base" indicating the
type, caller-callee relationship, source file, and "mnemonic equivalent"
of globals.

Cflow with the '-g' option gives the caller-callee database, source file
and line#, and some typing.

Here's one "simple" way to maintain compatibility.  Maintain a "compler
linkage table" that allows the compler to generate/resolve Global lables
in much the same way it currently treates local and static lables.

This, in effect means having "front-end" linkage to get referrences for
library routines, perhaps in the form of a "dynamic include file".

In short, instead of making C just a good "structured programming" language,
make it a good "structured design AND programming" language.

Additional Ideas?