🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #198

Can you nest subroutines in C?

#198
From: Wade Bickel
Date: Mon, 26 Jun 1989 12:16
103 lines
4603 bytes
----------------------------------------------------------------------------
-- This is a programming question.  If your not interested please skip    --
--                          this posting.                                 --
----------------------------------------------------------------------------

    Recently I switched from Benchmark Modula-2 to Lattice C.  While
writing a piece of code I discovered, much to my dismay, that I could
not express nested subroutines without choking the compiler.  Perhaps
someone can enlighten me as to how to do this.

Here is a pseudo-code example, in Modula-2.  It is used to create a circular
linked list of graphics level View/ViewPort/RasInfo/BitMap/Planes structures,
which I use for Multi-Buffering the screen.  Note that "#" = "!=". :^).

    MODULE NestedSubRtnExample;

    CONST NumBuffers = 3;

    TYPE
        ScreenBuffer = RECORD
                         V  : View;     (* \
                         VP : ViewPort; (*  \  These are just inited and
                         RI : RasInfo;  (*  /    tied together.  Copper lists
                         BM : BitMap;   (* /     must also be allocated.
                         scr: ADDRESS;  (* <-- of chip mem to be allocated *)
                       END;

    VAR MB  : ARRAY[0..NumBuffers-1] OF ScreenBuffer;

   (*-----------------------------------------------------------------------
    *  InitMB(n,h,w,d):   n = number of buffers to allocate.
    *                     h,w,d = dimentions of screen buffers.
    *-----------------------------------------------------------------------*)
    PROCEDURE InitMB(n,h,w,d : CARDINAL): BOOLEAN; 
                  (* ^^^^^^^------------------------USHORTs passed by value *)
      VAR
            ...  vars declared here as local to InitMB() would be visable
            ...    InitScreenBuffer() below.

      PROCEDURE InitScreenBuffer(N: CARDINAL): BOOLEAN;
      
        BEGIN
          ...initialize graphics structures in array MB[N], allocate planes[]
          ...  chip memory. Cleaup and return NIL pointer on alloc failure.
          ...  NOTE: uses h,w, and d in initaizations
          IF (N # 0) THEN
            MB[N].Next := InitScreenBuffer(N-1);
            IF (MB[N].Next = NIL) THEN
              ...cleanup this buffers memory allocs.
              RETURN(NIL);
            END;
          END;
          RETURN(ADR(MB[N]));
        END;

      BEGIN (* InitMB body starts here *)
        IF n = 0 THEN RETURN(FALSE);
        p = InitScreenBuffer(n-1);
        IF p = NIL THEN RETURN(FALSE);
        MB[0].Next = ADR(MB[n-1]);
        RETURN(TRUE);          
      END;


    BEGIN (* MAIN BODY OF PROGRAM *)

      IF NOT(InitMB(NumBuffers,320,200,3)) THEN RETURN(FALSE);
      ...go on with the rest of program.

    END.


    The nested subroutine InitScreenBuffer() is nested inside of InitMB().
The advantage to doing this is that it avoids either the declaration of
w,h, and d (width,height and depth respectively) as globals or passing them
as parameters to InitScreenBuffer() in which case they would appear three
times on the stack (18 bytes vs 6).

    In more complex algorithms involving trees of data I have found the use
of these psuedo globals very handy.   Also, anytime a segment of code needs
a large space of temporary data which will be visable to several routines, 
nesting is an easy, memory efficient method of allocating it.  I often bottle
up my entire program in this manner to avoid declaration of any global
variables at all.  While I have not written any, it seems this should be an
easy way to create reentrant code.
    

    I hope there is a way to create nested functions in C.  In general I find
I like C.  Especially the flexability of conditionals afforded in pointer
manipulations, which is much more powerful than that allowed in Modula-2.


                                                    Thanks,


                                                            Wade.



UUCP: {nosc ucsd hplabs!hp-sdd}!crash!pnet01!wade
ARPA: crash!pnet01!wade@nosc.mil
INET: wade@pnet01.cts.com
Technical Details
Message-ID: <4470@crash.cts.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!cwjcc!gatech!hubcap!ncrcae!ncr-sd!crash!pnet01!wade

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!cwjcc!gatech!hubcap!ncrcae!ncr-sd!crash!pnet01!wade
From: wade@pnet01.cts.com (Wade Bickel)
Newsgroups: comp.sys.amiga.tech
Subject: Can you nest subroutines in C?
Message-ID: <4470@crash.cts.com>
Date: 26 Jun 89 12:16:31 GMT
Sender: news@crash.cts.com
Organization: People-Net [pnet01], El Cajon CA
Lines: 103