    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Do birds in their little nests always agree?</title>
        <link>https://members.accu.org/index.php/articles/1440</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #4 - Feb 1994</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c233/">04</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-233/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+233/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Do birds in their little nests always agree?</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 01 February 1994 08:57:00 +00:00 or Tue, 01 February 1994 08:57:00 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<p>A complaint often raised by Pascal programmers moving to C or C++ is
the lack of nested functions in these languages. When pushed there
appears to be no need for them, just a want. Francis rattled the cage
of this topic in the last copy of Overload [see Uses of Classes with
only Private and Protected Constructors].</p>
<p>Functions in C exist at file scope, and in C++ they may also exist
in class scope. Should we appease Pascal programmers moving to C and
C++ by allowing functions to be defined in local scope, or should we
encourage them to write C and C++?</p>
<p>There are many interpretations of what function nesting means and
possibly not enough consideration of the consequences. I propose to
take a look at the issues involved in adding another definition scope
for functions, and what this means for programming styles and program
extensibility.</p>
<h2>The Algol approach</h2>
<p>Why would you expect to nest a function inside another function? A
number of ALGOL derived languages, notably Pascal, offer nested
procedures and functions that can operate on local variables. In C and
C++ this would look something like</p>
<pre>void DoSomething() {<br>  double X, Y; <br>  double Radius() {<br>    return sqrt(X * X + Y * Y) ; <br>  }<br>  double Theta() {<br>    return atan2(Y, X); <br>  }<br>}</pre>
<p>Convenient as this facility may look, the function definition is now
longer and therefore less readable than using functions defined at file
level &#8212; a situation that is often far worse in Pascal because of
inconsistent indentation practices. In this example two otherwise
general purpose functions have restricted availability in exchange for
empty argument lists. A couple of important questions to consider:</p>
<ol>
  <li>What happens when a pointer to a local function is returned</li>
  <li>What about recursive local functions?<br>
  </li>
</ol>
<p>While C has never been a bondage and discipline language, imposing a
specific view of good practice on its users, there is the unfortunate
possibility of returning a pointer to a function that uses <span
 style="font-family: monospace;">auto</span>
variables that will have fallen out of scope:</p>
<pre>void (*ReturnFunc()) ()<br>{<br>  int LocalVar;<br>  void NestedFunc()<br>  {<br>    ++LocalVar; <br>  }<br>  return NestedFunc;<br>}</pre>
<p>This is clearly unsafe, but so is returning a pointer to an <span
 style="font-family: monospace;">auto</span>
variable and that is not illegal in C. The next question raised is a
little more interesting. Consider the following function:</p>
<pre>void DoSomething()<br>{<br>  int Array[ArraySize];<br>  int Sum(size_t Arg)<br>  {<br>    return Arg-- &gt; 0<br>            ?&nbsp; Array[Arg] + Sum(Arg) : 0; <br>  };<br>}</pre>
<p>References to <span style="font-family: monospace;">auto</span>
variables outside the current block may be
implemented either by using a fixed offset to reach them down the
stack, or the largest possible activation record for a function is
placed on the stack and the variables are accessed as if they were
local to the current block. This only works for truly nested blocks
that do not interact with one another except their parents. The calling
environment for Sum changes, and hence the offset to <span
 style="font-family: monospace;">DoSomething</span>'s
local data is not constant, yet it must still access the same copy of
<span style="font-family: monospace;">Array</span>. There are a number
of methods for implementing this slightly
more complex arrangement, one of which is to pass the nested function a
pointer to the appropriate activation record on the stack to access the
local data. The eagle eyed OOPers among you may recognise the approach:
the <span style="font-family: monospace;">this</span> pointer. But
pointers to local functions implemented like this
would present a huge hole in the type system: their prototypes are now
incorrect as they take a silent extra argument.</p>
<p>Other approaches based around a secondary stack of thunks could be
used. To ensure correct deallocation the thunks would have to be bound
to the lifetime of the function. This would restrict the meaningful use
of nested function pointers to the lifetime of the defining function.</p>
<h2>Storage class</h2>
<p>The scope of a nested function is well defined, but what about its
lifetime? A nested function, as defined above, refers to stack data and
cannot be used meaningfully outside its scope, which implies that the
storage class of a nested function is&nbsp; <span
 style="font-family: monospace;">auto</span>.&nbsp; However,&nbsp;
they clearly have<br>
internal linkage, which is only possible for <span
 style="font-family: monospace;">static</span> entities. Clearly a
few rules are going to have to change to accommodate nested functions.<br>
</p>
<p>Given this, I think it is safe to say that ALGOL style nested
procedures have no place in either C or C++. A simpler approach is to
acknowledge that nested function definitions have <span
 style="font-family: monospace;">static</span> storage class
and may only refer to other non-<span style="font-family: monospace;">auto</span>
names in scope. For most uses
nested functions would simply be another scoping mechanism, but at
least function pointers no longer present a problem.</p>
<p>There is another issue that is relevant regardless of storage class:
the <span style="font-family: monospace;">goto</span>. I am no fan of
the <span style="font-family: monospace;">goto</span>, but it is there
and its demands on
the language must be met. C has three basic kinds of scope: local,
function and file. C++ adds class scope to this list. Only labels have
function scope &#8212; unless you wish to introduce Pascal-like label
declarations (no thanks). Does this mean that non-local <span
 style="font-family: monospace;">goto</span>'s would be
possible with nested functions in C and C++?</p>
<pre>void PathologicalLoop() <br>{<br>  void Iterate()<br>  {<br>    InnerLabel:<br>    goto OuterLabel;<br>  } OuterLabel:<br>  goto InnerLabel; <br>}</pre>
<p>A particularly unsavoury example &#8212; especially the jump to the inner
loop. Undoubtedly an extension of the rules defining <span
 style="font-family: monospace;">goto</span> destinations
and what function scope really means are required, with the likely
prohibition of jumps into a nested function. With all due respect to
jumps out of functions, C++ already has an exception handling mechanism
that is considerably more powerful and certainly more elegant.</p>
<h2>Use and reuse</h2>
<p>We have not yet asked why we would want to have nested functions.
All the objections have focused on the technical consequences of
introducing them into C and C++. The astute may have noticed nested
functions operating on local data bears a striking similarity to
certain capabilities offered in C++ but not in C. For nested functions
that may only operate on <span style="font-family: monospace;">static</span>
data this is a much less useful
feature. In fact, unless you can contrive an example of a non-reentrant
function that does not behave like an object, this feature borders on
being useless.</p>
<p>This is part of the problem with nested functions: in languages that
support them people often use nested functions where they actually
require a class instance that models a state machine. There are already
a number of functions masquerading as objects, and one of the most
obvious examples is <span style="font-family: monospace;">strtok</span>.
The use of nested functions in an OOP
language is thus suspect. Even the GNU compiler, which takes some
extraordinary liberties in extending both C and C++, only permits
nested functions in C, recognising either their irrelevance or their
extra complexity in C++.</p>
<p>What about the role of a function as a name space container for
other functions? Granted that you may not wish to broadcast a
function's existence to every entity in name space, but if we are
talking about methods declare them <span
 style="font-family: monospace;">private</span>, otherwise they should
be
declared as <span style="font-family: monospace;">static</span> within
a file. Not only are functions not data
objects, they are not packages either. In the Modula sense of the word,
functions make quite poor modules. Without an export interface they are
totally closed, and thus impervious to later design decisions requiring
a change in the interface.</p>
<p>Reuse is implicitly discouraged by nesting &#8212; abstractions that are
worth making once are probably worth using again. I am always surprised
when I see <span style="font-family: monospace;">struct</span>s, <span
 style="font-family: monospace;">enum</span>s and <span
 style="font-family: monospace;">typedef</span>s that are defined in
local scope.
These mechanisms hide details that would otherwise reduce portability
or encourage hard coding. They abstract the interface to functions and
the communication between program units. It is almost inevitable,
according to Murphy's Law, that something hidden in this way will be
required at a later date in another function within the same file. This
may happen if the functionality of the original module is extended and
so more functions require access to the type abstractions, or if the
original function gets too long and is broken up. Nested functions
would exacerbate rather than relieve this problem.</p>
<p>For data types this attitude has grown, I believe, from the top-down
view that structures are a simple repository for data and functions are
the real stuff of programs. 00 turns this on its head, and it is only
because it was deemed that the only difference between <span
 style="font-family: monospace;">struct</span>s and
<span style="font-family: monospace;">class</span>es would be in
default member access that local <span style="font-family: monospace;">class</span>es
in C++ are
a possibility. Even these are not exactly encouraged in C++ where
everything must be defined in the declaration. James Coplien, in his
excellent book <span style="font-style: italic;">Advanced C++
Programming Styles and Idioms</span>, relegates
local classes to an appendix where he uses them to emulate ALGOL style
block structured programming. This is perhaps the least useful and
least convincing section of the book. As an aside, the ISO committee
responsible for looking at OO extensions to Pascal has simply
disallowed local classes.</p>
<p>The pollution of name space is certainly an issue that should not be
ignored, and where a function must absolutely and definitely be used by
only one function classes should be used to handle this role for the
moment &#8212; they make much better modules than functions. It is also
significantly easier to make them extensible. Consider the following
three solutions to this problem:</p>
<ol>
  <li>
    <pre>void&nbsp; PublicFunc()<br>{<br>  void PrivateFunc()<br>  {<br>  }<br>}</pre>
  </li>
  <li>
    <pre>class Scope<br>{<br>  friend void PublicFunc();<br>  static void PrivateFunc();<br>};</pre>
  </li>
  <li>
    <pre>class Scope<br>{<br>public:<br>  static void PublicFunc(); <br>private:<br>  static void PrivateFunc();<br>}; </pre>
  </li>
</ol>
<p><span style="font-family: monospace;">PrivateFunc </span>is
declared for use only by <span style="font-family: monospace;">PublicFunc</span>.
What if
requirements change and one other function requires the use of
<span style="font-family: monospace;">PrivateFunc</span>? The first
example requires hacking out <span style="font-family: monospace;">PrivateFunc</span>
and
making it <span style="font-family: monospace;">static</span> within a
file in the best traditions of cut and paste
programming; the second adds another prototype to the friend list,
utilising a kind of selected client export idiom; and the third only
requires another public declaration, having recognised the coupling
issue by grouping the functions together in the same name space. Which
you prefer is clearly a matter of taste, but my own preference is not
for number 1.</p>
<h2>Conclusion</h2>
<p>The only language that I have ever used where procedural nesting
made sense was in occam where procedural units could either be executed
in sequence as normal procedures or in parallel as processes. Here the
idea of contained functionality made a lot more sense. Even with
processes the generality and reusability problem reared its ugly head.
The problems created by jumps, recursion and pointers were easily
solved: these features do not exist in occam.</p>
<p>C++ already has the ability to make functor objects that act like
functions, but these are potentially more versatile and flexible
inasmuch as they may be created for a purpose at runtime. This is a
style of programming explored more fully in Coplien's book.</p>
<p>Nesting of types within a class is a different case to function
nesting, and not just because of declaration versus definition. This
meets the criteria for communication and abstraction that I mentioned
earlier on. Either the types are used by clients of the class when
interacting with its instances, or the types are used between the
private methods of the class. Readability and implementability are
still important and anything other than trivial nested classes should
be hived off into a separate friend class so that the original type is
now represented by a class cluster [see <span
 style="font-style: italic;">Uses of Classes with only
Private and Protected Constructors</span> by Francis in the last issue].</p>
<p>Exceptions to rules have a nasty habit of creeping into language
definitions and taking root. A great many would have to be introduced
to both C and C++ to make any sense of nested functions. This might
keep some language lawyers happy, but I believe the case against them
is watertight.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
