From: kriss@rock.ibp.fr (Christophe GROSJEAN)
Subject: Re: C++ already *has* nested functions SO WHAT'S THE BEEF?
Reply-To: grosjean@masi.ibp.fr
Organization: Laboratoire MASI, Paris, France.
Date: Mon, 21 Dec 1992 17:21:01 GMT

In article <1992Dec21.080952.15309@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:

>   You see, C++ already provides nested functions.  I believe that even the
>   people who are bemoaning the lack of nested function in C++ are probably
>   aware of this fact (or would be if they thought about it for a moment)
>   and that in fact what we have here is a failure to communicate clearly.

Indeed C++ provide several ways of simulating nested functions,
the tricks to make it works has basically the 3 problems you
pointed out.


>	   o	We have to "invent" an otherwise useless and unnecessary
>		   containing struct, union, or class type in order to be
>		   able to nest functions.
>
>	   o	Due to the (silly?) prohibition against defining a function
>		   member of a block-local struct, union, or class type outside
>		   of (and after) its "parent" type, and due to the (silly?)
>		   rule that says that all functions defined *within* a class
>		   are implicitly `inline', our nested functions are always
>		   necessarily `inline' (when using this technique for nesting)
>		   even if we do not want them to be.
>
>	   o	Last but not least, although nested functions can legally
>		   reference *most* names of *most* kinds of things declared
>		   in a containing scope (including one local to a containing
>		   function) there is one small and mildly annoying exception
>		   to this general rule... i.e. we cannot access `auto' and
>		   `register' *objects* declared within a containing local
>		   scope.  Note that we *can* however reference the tags of
>		   enum, struct, union, and class, types, names declared in
>		   typedef statements, names of enumerators, function names,
>		   and names of static and extern objects which are declared
>		   in the containing (block) scope.


But, there is more to say about them : 

>   For my part, I would be satisfied if the ANSI/ISO C++ committee(s) would
>   add "nested functions" to C++ in such a way that the first two problems
>   on my list above could be eliminated.  But note that this could be done
>   with only a single minor syntax change (to allow function *definitions*
>   as well as function *declarations* within a local block) and one minor
>   semantic change, i.e. disallowing the mention of any name of a locally
>   declared function (except those declared `extern') in any context other
>   than a call to the given function.  These two minor changes would solve
>   the problems I'm concernd with, and they would be relatively easy and
>   painless for implementors to implement.  Also, just as importantly, they
>   would not add materially to the already horrendous complexity of the
>   language (which is already a terrible burden for all those who would try
>   to learn this language).

Well, i merely agree with you on this, the effect would be to make a
nested function declaration simpler. 

>   So why do people insist on attacking (and defeating) the third minor
>   problem listed above (regardless of costs)?

>   Well, it appears that some people have this mental model of "nested
>   functions" left over from the days when they programmed in Pascal, where
>   *anything* in a containing scope could be accessed directly.  Sadly, these
>   folks don't seem to "get" the fundamental idea which made C into the big
>   success that it is today... i.e. that it is *good* when potentially
>   expensive run-time actions (e.g. indirection through some number of
>   "static link" pointers) are made *explicit* to the programmer so that he
>   or she will be more aware of the potential effects these things may have
>   upon run-time performance.

Modula-2, as I saw it (I didn't tried *all* compilers) has no reason to envy C,
and particularly not the efficiency. However, scope rules are *perfectly*
consistent. So much for the idea of C success strongly related to its efficiency.
I use (and like) C and C++, and that's not a point. But it still seems strange
to me that you speak about *explicit indirection* when C++ obviously go
the other way (first step : passing vars by reference with &, second step :
virtual functions). I got the feeling that C++ is often confusing about data storage
and concepts.

>   Obviously, I have a strong disagreement with the folks who would (for the
>   sake of eliminating a very minor restriction which only makes a difference
>   in rare cases anyway) "hack" the language mercilessly (and thereby cause
>   yet another headache for implementors).

About the first and second problem, it seems easy enough to change,
but I think it could make the difference beetween a used feature and
an unused one (as I see it now !).

I don't think the third restriction you pointed out is a minor one.
For one reason : local static vars already have another meaning !
Those vars are initialized only *once* when you first execute the
containing function ! If you modify them the new value will stuck.

Doesn't matter in most cases. But it's a powerfull source of bugs
whenever you use recursive functions. What I say is that the problem
with static functions is not that they are statically allocated :
no problem if I have space enough, but that they are initialized only
once and won't be preserved in recursive call.

I can do what I want copying values beetween automatic and static vars,
but a *user* of a library expecting a function as an argument should'nt
bother about that, not saying that king of things is very error prone.

I would be perfectly happy with a *local* keyword meaning the value
is stored in a static var, but is saved before calls and initialised
every time my function is called : does it seem a difficult thing to do ?

I need it, I'm no maniac !

Best, regards

Newsgroups: comp.std.c++