Path: 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 ---------------------------------------------------------------------------- -- 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