[comp.lang.c] Using procedures instead of nested code

bvs@light.uucp (Bakul Shah) (09/09/89)

From article <7818@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones):
>From article <1989Sep7.162909.6638@light.uucp>, by bvs@light.uucp (Bakul Shah):
>> Note that the `benign' goto above can be removed also by use of a
>> procedure.  It can also improve readability (which is the underlying
>> theme here).
>
>Just use a "return" to jump out of the procedure, rather than a "goto"
>to jump out of the block. Sorry, but I don't see that as an improvement.

Well, yes and no.  It is not an improvement if the inner code is
simply broken out in a separate procedure in a mechanical fashion.
I was thinking of some restructuring/transformations on the way so
that one doesn't need to pass the environment via ptrs.  If this is
possible, the resultant procedure is usually a nice abstraction and
in my experience this is true more often than not.

To put it another way, nested loops and such act as a `complexity
alert' which prompt me to look for ways of reducing this complexity.
This isn't always possible but even the process of looking is very
useful.  This is not a hard and fast rule, merely a recommendation.
Anyway, I can illustrate this with an example of your choice.

>But there is a problem you seem to have overlooked. To keep the same
>functionality, you are going to have to pass pointers to all local variables
>into the newly created procedure, and replace all references to the local
>procedures with dereferenced pointers. (C++ "reference" parameters would
>save the day, but we're talking C, not C++)
>
>A block of code such as the one under discussion simply does not belong in
>another procedure, IMHO.

See above.  I didn't mean a mechanically constructed breakout.
Sorry, I didn't make that clear.

>> Also note that modern compilers are capable of inlining such one
>> time use procedures (with a little help from the user).
>> 
>
>Name one C compiler that does that.

GCC.  It does need the inline keyword (or is it __inline?).

>> On a related note, one feature I miss in C is nested procedures.
>
>Sorry, we can't seem to agree on anything. "Nested procedures" is
>just the automation of that pointer-creation/dereferencing I talked
>about above. Usually there's one pointer for each lexical level,
>(the "display"), and each nested procedure indexes off these for
>all the "scoped" variables. Phooey on that. (Well, okay, since
>we are now in the realm of what might be,  maybe one of
>those "modern compilers" could inline the code when appropriate.)

In circumstances where I *have* to use deep control structures OR
breakout inner code using either global vars or scads of ptr args OR
use a nested procedure, I claim nested procedures will provide the
best clarity (or least obfuscation :-).  They are a useful evil --
just like gotos or global variables.

>> Without them one ends up using global variables or passing lots of
>> arguments or avoids using a procedutre altogether because the code
>> that can be broken off into a separate procedure is just too tightly
>> coupled with its environment and would make for a very messy
>> interface (or force global var usage).  Oh well....
>> 
>
>At last! Agreement.
>
>This is indeed a problem. But it's a static problem. No need to
>bring a runtime display into the picture.
>
>One way to handle it might be a convenient macro mechanism:

Macros are a poor man's nested procedures!  Besides, they don't
allow recursion.

There are other ways that don't use runtime displays and are very
efficient for the majority of nested procedure uses.

Typically most nested procedures use their parent's variables and
are not nested very deeply.  A common mechanism is to pass a ptr to
parent's frame rather than create a display.  Top level procedures
with no nested procedures can be treated exactly like C procedures
(I think the MetaWare C compiler does this -- yes, their C has
nested procedures).  If a parent's vars are accessed frequently, the
parent-frame-ptr can be kept in a register, just like the local-
frame-ptr, and now either frame can be accessed equally fast.  And
yes, nested procedures should be inlined if possible -- not very
hard to do, actually.

But the issue here is readability -- why are nested procedures bad
for that?

>Or, I could get by just fine with an editor that could name and
>hide blocks, and store such info with the source files. (Hypertext?)

I'd like an outline editor myself but that is not sufficient.

-- Bakul Shah <..!{ames,sun,ucbvax,uunet}!amdcad!light!bvs>