<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Adoption of C99's __func__ predefined identifier and improved default argument behavior</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
<!--
.base	{font-size: small}
h1,h2	{font-size: medium;}
h3	{font-size: small;}
-->
</style>
</head>
<body class="base"> 
<div align="right"> 
  <table> 
    <tr> 
      <th scope="row"><div align="right">Doc No:</div></th> 
      <td>SC22/WG21/N1642 04-0082</td> 
    </tr> 
    <tr> 
      <th scope="row"><div align="right">Date:</div></th> 
      <td>April 9, 2004 </td> 
    </tr> 
    <tr> 
      <th scope="row"><div align="right">Project:</div></th> 
      <td>JTC1.22.32</td> 
    </tr> 
    <tr> 
      <th scope="row"><div align="right">Reply to:</div></th> 
      <td>Alex Rosenberg</td> 
    </tr> 
    <tr> 
      <th scope="row">&nbsp;</th> 
      <td>Sony Computer Entertainment America</td> 
    </tr> 
    <tr> 
      <th scope="row">&nbsp;</th> 
      <td>alexr@spies.com</td> 
    </tr> 
  </table> 
</div> 
<h1>Adoption of C99's __func__ predefined identifier and improved default argument behavior</h1> 
<h2>Problem</h2> 
<p>On-going compatibility with C is important for C++, both for ease of upgrading a program to C++ and for support of compilers that implement both languages. C99 introduces several new features which break compatibility. Many compilers already implement some support for C99's <code>__func__</code> predefined identifier in C++ without the benefit of standardization.</p> 
<p>Portable ways to debug C++ programs are an area where the language is lacking. Improved debugging facilities assist in all manners of use of C++ as debugging is debatably the largest proportion of time spent during development.</p>
<p>This document proposes adopting <code>__func__</code> from C99 with additional specification of places in which it may appear. It also proposes changes to default arguments and provides additional contexts in which default arguments may be used.</p>
<p>Motivating examples are illustrated, including a portable stack crawl mechanism.</p>
<h2>C99 Background</h2> 
<p>Much like the preprocessor provides <code>__FILE__</code> and <code>__LINE__</code>, some compilers have extended the notion with additional predefined macros such as <code>__FUNCTION__</code> and <code>__PRETTY_FUNCTION__</code>.</p> 
<p>C99 adds the notion of a &quot;predefined identifier&quot; and defines just one, <code>__func__</code>. The intent of <code>__func__</code> is similar to <code>__FUNCTION__</code>, but the delivery is different. To quote ISO/IEC 9899:1999:</p> 
<blockquote> 
  <h3> 6.4.2.2 Predefined identifiers</h3> 
  <p> 1 The identifier <code>__func__</code> shall be implicitly declared by the translator as<br /> 
    if, immediately following the opening brace of each function definition, the<br /> 
    declaration</p> 
  <blockquote>
    <p><code>static const char __func__[] = &quot;<em>function-name</em>&quot;;</code>
    </p>
  </blockquote>
  <p> appeared, where <em>function-name</em> is the name of the lexically-enclosing function.</p> 
  <p> 2 This name is encoded as if the implicit declaration had been written in the<br /> 
    source character set and then translated into the execution character set as<br /> 
    indicated in translation phase 5.</p> 
  <p> 3 EXAMPLE Consider the following code fragment:</p> 
  <blockquote>
    <p><code>#include &lt;stdio.h&gt;<br /> 
      void myfunc(void)<br /> 
      {<br /> 
&nbsp;&nbsp;printf(&quot;%s\n&quot;), __func__);<br /> 
&nbsp;&nbsp;/* ... */<br /> 
      }</code> 
    </p>
  </blockquote>
  <p> Each time the function is called, it will print to the standard output stream:</p> 
  <blockquote>
    <p><code>myfunc</code></p>
  </blockquote>
</blockquote>
<h2>Proposal</h2>
<h3>NTBS Contents</h3>
<p>This basic feature from C99 requires some modification to integrate with C++. The common presence of &quot;mangled&quot; names and of language features such as strict typing, overloading, operators, and templates present a quandary regarding the content of the string. The author believes that this is the &quot;bicycle shed&quot; for this proposal and as such, I would propose that this is substantially similar to <code>std::type_info</code> and should be dealt with by declaring the NTBS contents to be implementation-defined with some suggestions.</p>
<p>Firstly, that the implementation should define a predictable and documented naming scheme. If they choose to emit mangled names, they should document their mangling scheme and provide a means to demangle a given string.</p>
<p>Secondly, they should endeavor to guarantee that these strings are unique in a program. This has impact on static functions, anonymous namespaces, and local or anonymous classes, for which they should consider including the file name containing the translation unit in the string.</p>
<h3>Defined Wherever Expressions May Occur</h3>
<p>C99 does not provide for the existence of <code>__func__</code> where there is no lexically-enclosing function as occurs with static initialization, namespace scope, etc.</p>
<p>It is proposed to modify C99's definition to define that <code>__func__</code> also works from static initialization and provides a unique but implementation-defined string (most likely including the file name of the translation unit). For example:</p>
<blockquote>
  <p> <code>// at namespace scope<br />
    const char *foo = __func__;</code></p>
</blockquote>
<p>In this case, foo shall contain an implementation-defined string that uniquely identifies the file-level scope where it is initialized. The file name or a full or partial path to the file are typical implementation choices.</p>
<p>This enhancement in cooperation with the changes to default arguments allows for a more complete solution to the motivating examples. </p>
<h3>Default Arguments and Deferred Behavior</h3>
<p>&quot;..default arguments are logically redundant and at best a minor notational convenience.&quot; [D&amp;E, 2.12.2]</p>
<p>Default arguments have the unique property that a change made only in the called function definition may change all existing callers of the function. With this observation, default arguments border on both closures and AOP.</p>
<blockquote><code>#include &lt;iostream&gt;<br />
const char *foo(const char *f = __func__) { return f; }<br /><br />
int main(int argc, const char* argv[])<br />
{<br />
&nbsp;&nbsp;std::cout &lt;&lt; foo();<br />
}</code></blockquote>
<p>There are several potential choices for <code>__func__</code>'s value in this default argument. Since <code>__func__</code> is already in a new class of identifier  and C99 lacks default arguments, there is even more flexibility.</p>
<p>It is proposed here that <code>f</code> shall refer to the value of <code>__func__</code> as if the name binding had occurred at the call site inside main. That is, this program shall print &quot;<code>main</code>&quot; or whatever <code>main</code>'s NTBS is defined to be with the compiler being used.</p>
<p>This would require that <code>__func__</code> be defined to be a &quot;deferred identifier&quot; instead of the &quot;predefined identifier&quot; terminology used in C99. It would be bound at the latest possible place and then subject to the same &quot;predefined&quot; behavior as found in C99.</p>
<h3>Generalized Syntax </h3>
<p>Instead of defining <code>__func__</code> as a &quot;deferred identifier&quot; and creating specific new rules for this class of identifier to permit the uses described here, it is possible to define a generalized syntax for the name-binding rules described here.</p>
<p>One possible syntax would be &quot;<code>::::identifier</code>&quot; to bind to whatever is named as <code>identifier</code> in the context where a default argument is being expanded or the point of instantiation of a template default argument. The mnemonic here is that &quot;<code>..</code>&quot; refers to the parent directory in several major file systems. Other syntaxes are possible and this should just be considered illustrative.</p>
<p>With a generalized access to name binding in the expansion of a default argument of the point of instantiation of a template, <code>__func__</code> and the other proposed &quot;deferred identifiers&quot; would simply be C99-style &quot;predefined identifiers.&quot; To return to an earlier example: </p>
<blockquote><code>#include &lt;iostream&gt;<br />
  const char *foo(const char *f = ::::__func__) { return f; }<br />
  <br />
  int main(int argc, const char* argv[])<br />
  {<br />
&nbsp;&nbsp;std::cout &lt;&lt; foo();<br />
  }</code></blockquote>
<p>Would print &quot;<code>main</code>&quot; as before. To borrow from 8.3.6 p5:</p>
<blockquote>
  <p><code>int a = 1;<br />
    int f(int);<br />
    int g(int x = f(::::a));</code></p>
  <p><code>void h() {<br />
&nbsp;&nbsp;a = 2;<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int a = 3;<br />
&nbsp;&nbsp;&nbsp;&nbsp;g(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// g(f(::::a))<br />
&nbsp;&nbsp;}<br />
    }</code></p>
</blockquote>
<p><code>g</code> would be called with the value <code>f(3)</code>.</p>
<p>Further examples in this document skip the generalized syntax and use the &quot;deferred identifier&quot; syntax instead, but either syntax would satisfy the needs of the motivating examples. </p>
<h3>Default Arguments and Operator Overloads </h3>
<p>One of the motivating examples below is a portable stack crawl facility. With the changes proposed thus far, operator overloads, destructors, and library functions cannot participate in such a stack crawl mechanism.</p>
<p>Operator overloads would be enhanced to support any number of arguments requiring default arguments for each one after the existing mandated arguments necessary for their normal syntactical use.</p>
<blockquote>
  <p><code>struct A {<br />
  &nbsp;&nbsp;A operator+(const A&amp; a, int b = 1);<br />
  &nbsp;&nbsp;A operator+(int b = 2);<br />
    };<br />
  A operator+(const A&amp; a, const A&amp; a1, int b = 1);<br />
  A operator+(int b = 2);</code></p>
</blockquote>
<p>The first operator of each pair is the usual binary operator for addition, accepting an additional default argument. The second one is the unary addition operator. Overload is as before, ignoring any arguments having a default. If all arguments have a default, it is as if the operator had a void argument list. </p>
<p>Explicit calls to operator overloads may substitute for the default arguments as with normal functions.</p>
<p>The only operator overload  which this change does not work for is the function call operator.</p>
<h3>Default Arguments and Destructors</h3>
<p>As with operator overloads, destructors are similarly modified to accept an argument list consisting only of arguments having defaults. </p>
<h2>Motivating Examples</h2>
<h3>Portable Stack Crawls</h3>
<p>There exists no means to perform any form of portable stack crawl. This is a major omission from the language. Every non-portable stack crawl solution the author has encountered exposes all manner of implementation details and offers little more than would be obtained doing assembly-level debugging.</p>
<blockquote>
  <p> <code>list&lt;const char*&gt; crawl;</code></p>
  <p><code> void dump_stack_crawl(void)<br />
    {<br />
    &nbsp;&nbsp;for (list&lt;const char*&gt;::iterator i = crawl.begin(); i != crawl.end(); ++i)<br />
    &nbsp;&nbsp;{<br />
    &nbsp;&nbsp;&nbsp;&nbsp;cout &lt;&lt; *i &lt;&lt; endl;<br />
    &nbsp;&nbsp;}<br />
    }</code></p>
  <p><code> void f(... , const char* caller = __func__)<br />
    {<br />
    &nbsp;&nbsp;crawl.push_back(caller);<br />
    &nbsp;&nbsp;crawl.push_back(__func__);<br />
    &nbsp;&nbsp;...<br />
    &nbsp;&nbsp;crawl.pop_back();<br />
    }</code></p>
</blockquote>
<p>Here, <code>f()</code> or similarly instrumented functions and their unmodified callers are tracked in a portable partial stack crawl. With judicious use of the preprocessor, such a tracing facility can be selectively enabled or disabled to narrow the scope of debug output.</p>
<h3>Mutation Tracking</h3>
<p>Given a very complex data structure, such as the nests of DAGs found in the back-end of an optimizing compiler, a common debug scenario is to wade though dumps of the structure after each possible transformation, hunting for the point at which something went wrong. With multitudinous small graph transformations being performed, this can be like looking for a needle in a haystack.</p>
<p>Given that these structures are often comprised of many interlinked nodes of objects sharing a common base class, one can envision such an example:</p>
<blockquote>
  <p> <code>class Node<br />
    {<br />
    &nbsp;&nbsp;...<br />
    &nbsp;&nbsp;virtual void perform_some_transformation(const char* caller = __func__);<br />
    &nbsp;&nbsp;...<br />
    private:<br />
    &nbsp;&nbsp;const char* last_mutation;<br />
    }<br /><br />
    Node a;</code></p>
</blockquote>
<p>Each caller would then call <code>a-&gt;perform_some_transformation()</code>. Each <code>Node</code> in the complex structure would then remember who last asked that it be changed. Similar manually-performed tracking has proven beneficial to the author in the past.</p>
<p>This can be accomplished today in C++ using <code>__FILE__</code> and <code>__LINE__</code> combined with other preprocessor machinations, but these strings are often different among the differing versions of code being worked on by a multiple engineer team. Function names are much less likely to change and are more useful with modern integrated development environments that shun the traditional text file editor model in favor of an object browser.</p>
<h2>Interactions</h2>
<p>As noted in footnote 60 in C99, since <code>__func__</code> begins with a double underscore, it was already reserved by the implementation. Defining <code>__func__</code>'s behavior in additional contexts such as namespace scope and default arguments runs the risk of future versions of C supporting incompatible behavior. </p>
<p>The example stack crawl facility is not complete as there is no solution presented for unmodified library functions nor for overloads of the function call operator. </p>
<h2>Implementability</h2>
<p>Several compilers already implement C99's <code>__func__</code> in some C++ compilation modes. None that the author is aware of implement the extensions proposed, although at least one (gcc) allows the use of <code>__func__</code> at global scope with a warning, producing an empty string.</p>
<p>There exist several implementation possibilities for default argument handling in compilers. Although implementations like thunks and function cloning are possible, the author has only ever seen compilers that integrate the default argument expressions at each call site. Even if a compiler chooses a strategy like thunks or function cloning, that does not preclude the default argument rules presented here, although it would require them to adopt an integration strategy for at least the default arguments containing &quot;deferred identifiers&quot; or the similar generalized syntax.</p>
<h2>Extension Ideas</h2>
<h3>Library Demangler </h3>
<p>An earlier version of this proposal (N1534) as well as  postings on comp.lang.c++.moderated from various authors suggested that an NTBS describing a specific source location was insufficient and more compile-time introspection was necessary. Toward that end, <code>__class__</code> and <code>__namespace__</code> were suggested.</p>
<p>It may well be better to propose a library-only solution in the <code>std</code> namespace to provide demangling and introspection of a given NTBS accessed via either <code>__func__</code> or <code>std::type_info-&gt;name()</code>. No class design is presented here, but it bears mention in the context of this discussion.</p>
<h3>Additional Deferred Identifiers</h3>
<p>In addition to defining <code>__func__</code> as a deferred identifier, <code>__file__</code> and <code>__line__</code> are proposed. They would take on their respective values at the call site for a default argument expansion, or the point of instantiation for a template default argument. These additional deferred identifiers permit the following type of code:</p>
<blockquote>
  <p><code>void assert(bool b,<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* file = __file__,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long line = __line__,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* func = __func__)<br />
    {<br />
    &nbsp;&nbsp;if (!NDEBUG &amp;&amp; !b)<br />
    &nbsp;&nbsp;{<br />
    &nbsp;&nbsp;&nbsp;&nbsp;std::cerr &lt;&lt; &quot;Assertion failure in &quot; &lt;&lt; func<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt; &quot; in file '&quot; &lt;&lt; file<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt; &quot;' at line &quot; &lt;&lt; line<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt; &quot;.&quot; &lt;&lt; std::endl;<br />
    &nbsp;&nbsp;&nbsp;&nbsp;abort();<br />
    &nbsp;&nbsp;}<br />
    }</code></p>
</blockquote>
<p>While this representative example can not be used as a replacement for <code>assert</code> as-is, a similar improved <code>assert</code> replacement could be constructed as a library extension, eliminating one popular use of the preprocessor. </p>
<p>It is also worth poining out that a constructor called from a <em>throw-expression </em>could easily participate in  a portable stack crawl mechanism or similar using the facilities described here. </p>
<h2>Citations</h2>
<table>
  <tr>
    <th scope="row">[D&amp;E]</th>
    <td>Stroustrup, B. The Design and Evolution of C++. Addison-Wesley, Reading, MA. 1994. ISBN 0-201-54330-3</td>
  </tr>
</table>
<p>&nbsp;</p>
</body>
</html>
