From -2640687046406879956
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,a69618ea97f65037
X-Google-Attributes: gidf78e5,public
From: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Subject: Re: nested functions
Date: 1998/04/29
Message-ID: <35477A9B.3D6@noSPAM.central.beasys.com>#1/1
X-Deja-AN: 349491162
Content-Transfer-Encoding: 7bit
Approved: stephen.clamage@sun.com (comp.std.c++)
References: <6hac23$8lb$1@news2.isdnet.net> <353b85b9.0@news.iprolink.ch> <sfn2dcncm2.fsf@bidra168.bbn.hp.com> <35459993.3BC581B0@physik.tu-muenchen.de> <199804281743.NAA18001@calumny.jyacc.com> <35472A6D.562EA04C@physik.tu-muenchen.de>
Mime-Version: 1.0
Reply-To: david.tribble@noSPAM.central.beasys.com
Originator: clamage@taumet
X-NNTP-Posting-Host: dalnt9.beasys.com
Content-Type: text/plain; charset=us-ascii
Organization: BEA Systems, Inc.
Newsgroups: comp.std.c++


Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
>>> Other than nested functions, closures would cause problems with the 
>>> C++ object model. Look for example at the following code:
>>>
>>> struct X { };
>>> typedef X* (*fun)();
>>> fun f(int i)
>>> {
>>>   X x;
>>>   X* c1() { return &x; }
>>>   X* c2() { return 0; }
>>>   return i > 0 ? c1 : c2;
>>> };
>>>
>>> Now, when should the destructor of x be called?

Hyman Rosen wrote:
>> At the normal time, right before f returns. Closures in C and C++ do
>> not, and are not meant to, behave like closures in Scheme. C/C++ is
>> not a garbage-collected language, and automatic variables do not
>> survive the exit of their block. In your example, users of the return
>> value of f may will access a dangling pointer. Mot only x, but c1 and
>> c2 themselves no longer exist after f returns. Closures in C/C++ are
>> still needed for mutually recursive or further nested inner
>> functions, however.

Christopher Eltschka wrote:
> But as long as f didn't return, you don't need a closure mechanism,
> as the usual nested function mechanism would work well (you could, of
> course, define this as a specialized closure, but then you could
> as well say C++ already supports nested functions, but limited to
> the first level, which is functions at global scope). As I see them,
> closures are just there to ensure that variables of the outer scope
> survive long enough.
> Note that f.ex. Pascal doesn't have closures, but supports nested
> functions at arbitrary levels including direct and indirect
> recursion. This more than proves that closures are not necessary
> for this.

Not exactly.  In compiler terminology, the nested functions need
a "display block" in their call activation records.  Each display
allows the nested function to access its outer function's local
variables in addition to its own local variables, and works very
well with recursion.

An example illustrates more of the problems:

    class Foo
    {
        int   bar(int i)      // A member func
        {
            int  baz()        // A nested func
            {
                count += i;   // Accesses this->count and bar.i
            };

            int  boz()        // Another nested func
            {
                count -= i;   // Accesses this->count and bar.i
                if (...)
                   boz();     // Recursive call
            };

            if (...)
                baz();
            else
                boz();
        }

        int     count;        // Member of *this
    };

Here, both nested functions baz() and boz() access a local variable
(i) of their outer function bar().  They also access a member (count)
of the 'this' object of bar(), which is technically also a local
variable.  Note than boz() has to access the same 'count' and 'i'
locals even if it's been called recursively.

All of these are solved by some form of "display" activation record.
Pascal, which supports nested routines, uses this kind of mechanism.
Apparently g++ uses something similar (called a "trampoline") but
that has less overhead for non-nested routines.

-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




