From 2199866270071158248
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,fb1a92fa405c930c
X-Google-Attributes: gidf78e5,public
From: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Subject: Re: nested functions
Date: 1999/06/16
Message-ID: <376761DB.603FE6F1@physik.tu-muenchen.de>#1/1
X-Deja-AN: 490288083
Content-Transfer-Encoding: 7bit
Approved: Fergus Henderson <fjh@cs.mu.oz.au>
References: <7jd4c5$nup$1@nnrp1.deja.com> <7jjjr6$r02$1@nnrp1.deja.com> <7jma5c$i85@abyss.West.Sun.COM> <FD38vK.CC4@research.att.com> <7jrpss$ogk$1@nnrp1.deja.com> <FqA83.38464$wk2.553149@newscene.newscene.com> <37659D89.565ACF7D@technologist.com> <7k5ncv$n8u$1@nnrp1.deja.com> <376690B6.6231FB13@technologist.com>
X-Original-Date: Wed, 16 Jun 1999 10:35:39 +0200
X-Accept-Language: German/Germany, de-DE, German, de, en
Content-Type: text/plain; charset=us-ascii
X-Complaints-To: news@news.unimelb.edu.au
X-Trace: izvestia.its.unimelb.edu.au 929547018 19787 128.250.29.16 (16 Jun 1999 15:30:18 GMT)
Organization: [posted via] Leibniz-Rechenzentrum, Muenchen (Germany)
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUAN2fC4eEDnX0m9pzZAQEKcwGAiUAh+TTby7wN02RCztGDct57/CRC1xzg tdEsLNWwUaN3SE1VMfySEaMF/6+B9IbG =cBdz
Mime-Version: 1.0
NNTP-Posting-Date: 16 Jun 1999 15:30:18 GMT
Newsgroups: comp.std.c++

David R Tribble wrote:

[...]

> >> P.S.  I personally don't see any need for nested functions.
> >
> > I do. (It's true no single language feature is have-it-or-die,
> > though.)
> 
> Please provide a convincing example; no one's done that yet.

One from real life:

extern "C"
 void fortran_integration_routine_(double(*)(double&),
                                   int const& start, int& end,
                                   double const& prec,
                                   double& result);

double calc_something(double param1, double param2)
{
  // I wish I had this
  double foo(double& pd)
  {
    return param1 + pd*param2;
      // of course, the real function was more complex
  }
  double result;
  fortran_integration_routine_(&foo, 1, 3, 1e-10, result);
  return result;
}

Of course, the real function was much more complex (and the
integral was two-dimensional, so the integration was called
recursively).

> 
> > The problem is, they are hard to implement in the context of the
> > C++ language.
> 
> My guess is that nested functions would be no more harder to
> implement than exception handling.
> 
> Oh, and by the way, how do nested functions complicate exception
> handling?  No one's discussed that either.

Do they? I don't think so. For the EH mechanism, the only difference
between global and local function is an aditional local context
parameter. Quite similar to the additional this parameter in classes.

> 
> A nested function requires a slightly more complex invocation frame,
> called a "display" (see chap.7 of the Red Dragon compiler book),
> which allows it to access its outer function's local variables (to
> any arbitrary nesting level) in addition to its own local variables.
> A display also handles recursion, allowing the function to call
> itself while still maintaining accessibility to the proper level
> of local and outer local variables.  This in itself is not hard to
> do for C++.

Look at the Borland Pascal implementation: The function just
gets as additional parameter the local context of the surrounding
function. That is, the code

void foo()
{
  int i=2;
  void bar()
  {
    int j=3;
    void baz(int k)
    {
      i=j+k;
    }
    baz(3);
  }
  bar();
}

would be translated into (qualitatively)

void baz(int k, __bar_local_context* parent)
{
  parent->parent->i = parent->j+k;
}

void bar(__foo_local_context* parent)
{
  int j=3;
  baz(3, __own_local_context);
}

void foo()
{
  int i=2;
  bar(__own_local_context);
}

As you see, accessing variables through more levels gets more
expensive. I don't see that as a big problem.

> 
> What is hard is adding yet another kind of function pointer, which
> allows the compiler to properly invoke a pointed-to local function
> so that its invocation frame is properly constructed.  I'm led to
> the conclusion that the compiler needs to know it's a local
> function pointer, distinct from a "normal" function pointer, so that
> this can occur; this implies a new syntax for distinguishing between
> the two kinds of pointers.  (I already suggested the syntax
> '({}::* fp)()' in another post.)  Such a pointer must contain extra
> information such as the number of nesting levels needed by the
> pointed-to function's display; perhaps such a pointer points to
> a static "display descriptor" which contains such information,
> much like an object's _vtbl pointer points to a static "class
> descriptor table".

This is the most obvious solution. However, another solution exists
which encodes the extra information not in the pointer itself, but
in the code it points to, which is a dynamically created trampoline.
That solution has the advantage that you can use normal function
pointers, and pass them to non-C++-functions.

> 
> But I still don't think nested functions are that useful.

I think they are.
---
[ 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              ]



