🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #4164

Re: Nested functions

#4164
From: Duncan Booth
Date: Tue, 03 Oct 1995 08:43
82 lines
4176 bytes
In article <1995Sep28.144829.1579@ittpub>, wil@ittpub.nl (Wil Evers) wrote:
> 
> Please note that I did *not* suggest a special syntax for 'pointer to  
> whatever nested function', but a special syntax for 'pointer to function  
> nested in <this other function>'. By saying that, I meant that the  
> enclosing function of the function pointed to should be a part of the type  
> of the function pointer, so the compiler can do a check to make sure such  
> a pointer is never used in a context where the locals of the enclosing  
> function might do not exist. Basically, such a pointer would only be legal  
> in the enclosing function and the functions it encloses. A pointer to a  
> non-nested function would simply be the simplest of these: a pointer to a  
> function nested in no other function, which is therefore legal everywhere  
> in the program.

You are missing the point that the commonest use of such pointers to
functions would be as callbacks. For example it would be extremely
useful if qsort took a pointer to a nested function as the comparison
function. This means that for nested functions to be useful they need
to have the same type as any other function with the same
parameters/results.

Personally I would like to see plain nested functions without the
ability to access outer variables. When access to outer variables is
needed in a function, it should be passed a pointer to the variable.

If you really want the ability to get at outer variables in nested
functions, then I think the way to do it corresponding most closely
to the C philosophy is to make it explicit. How about a new 'type'
called (for the sake of argument) __frame, and a reserved word
__currentframe? Here is how you might use it:

void CallIt(void (*)(__frame,int) func, __frame f)
{
        func(f, 5);
}

void A(int x)
{
    int y;
    void A1(__frame f)
    {
        int z = 5;
        void A2(__frame f, int w)
        {
                f.f.y = f.z + f.f.x + w;
        }
        CallIt(A2, __currentframe);
        f.A3(f.__currentframe);
    }
    void A3(__frame f)
    {
    }
    A1(__currentframe);
}

Note that the __frame type here is using the structure syntax so that
any references to outer variables are explicit, there are no hidden
traps if an outer local variable is renamed. Pointer syntax might be
more appropriate though? Implementation of this code would mean no
changes are required to the called conventions of any functions and
code that does access not outer variables can still get the benefit
of nested functions for scoping purposes without any loss of
efficiency.

Admittedly the __frame type is a bit like void * in that there is no
check that the frame is associated with the correct function and the
call to A3 in my example shows that you cannot always just blindly
pass in the current frame. Of course there is substantial scope for
compiler or runtime checks to ensure that the frames don't get mixed
up.

P.S. I just wrote this off the top of my head so I am sure there are
lots of wholes in this suggestion, for a start I think there should
be some distinction between the frame argument that is to be used to
access outer variables and the frame argument to CallIt which cannot
be used to access anything until it is passed to another function.

--
Duncan Booth                                             duncan@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
       Be careful of your thoughts, they may become words at any moment.
Technical Details
Message-ID: <xePcwkXAi0eG084yn@rcp.co.uk>
Path: arc1-ca.pugleaf.net!kate.ibmpcug.co.uk!rcp!news
References: <449bs9$r8c@news0.rain.rg.net> <1995Sep28.144829.1579@ittpub>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!kate.ibmpcug.co.uk!rcp!news
From: Duncan@rcp.co.uk (Duncan Booth)
Newsgroups: comp.std.c
Subject: Re: Nested functions
Message-ID: <xePcwkXAi0eG084yn@rcp.co.uk>
Date: Tue, 03 Oct 1995 09:43:29 +0100
References: <449bs9$r8c@news0.rain.rg.net> <1995Sep28.144829.1579@ittpub>
Distribution: world
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Newsreader: Yarn 0.84 with YES 0.20.B0509
X-Info: YES is the Yarn Editor Shell, a freeware utility for Yarn!