<html>
<style>
ins {background-color:#FFFFA0}
del {background-color:#FFFFA0}
</style>
<body>
<h1>New Function Declarator Syntax Wording</h1>
Jason Merrill
<br>2008-02-28
<br>Document Number N2541=08-0051
<br>Revision 11

<h2>Proposed wording</h2>

<h3>7.1.6.4p2+</h3>
<p>Otherwise (<tt>auto</tt> appearing with no type specifiers other
  than <i>cv-qualifiers</i>), the <tt>auto</tt> <i>type-specifier</i>
  signifies that the type of an object being declared shall be deduced from
  its initializer<u> or specified explicitly at the end of a function
  declarator</u>. <s>The name of the object being declared shall not appear
  in the initializer expression.</s>

<p><u><tt>auto</tt> can appear with a function declarator with a
  late-specified return type (8.3.5) in any context where such a declarator
  is valid, and the use of <tt>auto</tt> is replaced by the type specified
  at the end of the declarator.</u>

<p><u>Otherwise, the type of the object is deduced from its initializer.
  The name of the object being declared shall not appear in the initializer
  expression.</u> This use of <tt>auto</tt> is allowed when declaring
  objects in a block (6.3), in namespace scope (3.3.5), and in
  a <i>for-init-statement</i> (6.5.3).  [...]

<h3>8p4</h3>
<blockquote><pre>
<i>direct-declarator:
	declarator-id
	direct-declarator</i> ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub>
<u>	direct-declarator</i> ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></i> -> <i>type-id</u>
	direct-declarator</i> [ <i>constant-expression<sub>opt</sub></i> ]
	( <i>declarator</i> )<i>
</i></pre></blockquote>

<h3>8.1p1</h3>
<blockquote><pre>
<i>direct-abstract-declarator:
	direct-abstract-declarator<sub>opt</sub></i> ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></i>
<u>	direct-abstract-declarator<sub>opt</sub></i> ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></i> -> <i>type-id</u>
	direct-abstract-declarator<sub>opt</sub></i> [ <i>constant-expression<sub>opt</sub></i> ]
	( <i>abstract-declarator</i> )<i>
</i></pre></blockquote>

<h3>8.3.5p1</h3>

<p>In a declaration <tt>T D</tt> where <tt>D</tt> has the form

<blockquote><pre>
<tt>D1 ( </tt><i>parameter-declaration-clause</i><tt> ) </tt><i>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></i>
</pre></blockquote>

and the type of the contained <i>declarator-id</i> in the declaration
<tt>T D1</tt> is "<i>derived-declarator-type-list</i> <tt>T</tt>,"
the type of the <i>declarator-id</i> in <tt>D</tt>
is "<i>derived-declarator-type-list</i> function of
(<i>parameter-declaration-clause</i>)
<i>cv-qualifier-seq<sub>opt</sub></i> <i>ref-qualifier</i><sub>opt</sub>
returning <tt>T</tt>"<s>; a type of this form is a
<i>function type</i>*.</s>

<p><u>In a declaration <tt>T D</tt> where <tt>D</tt> has the form

<blockquote><pre>
<tt>D1 ( </tt><i>parameter-declaration-clause</i><tt> ) </tt><i>cv-qualifier-seq<sub>opt</sub> ref-qualifier<sub>opt</sub> exception-specification<sub>opt</sub></i><tt> -> </tt><i>type-id</i>
</pre></blockquote>

and the type of the contained <i>declarator-id</i> in the declaration
<tt>T D1</tt> is "<i>derived-declarator-type-list</i> <tt>T</tt>,"
<tt>T</tt> shall be the single <i>type-specifier</i> <tt>auto</tt> and
the <i>derived-declarator-type-list</i> shall be empty.

Then the type of the <i>declarator-id</i> in <tt>D</tt> is "function of
(<i>parameter-declaration-clause</i>) <i>cv-qualifier-seq</i><sub>opt</sub>
<i>ref-qualifier</i><sub>opt</sub>
returning <i>type-id</i>".

Such a function type has a <i>late-specified return type</i>.

<p>The <i>type-id</i> in this form includes the longest possible sequence
  of <i>abstract-declarators</i>. [Note: this resolves the ambiguous
  binding of array and function declarators.  [Example:
<pre>
    auto f()->int(*)[4]; // function returning a pointer to array[4] of int
                         // not function returning array[4] of pointer to int
</pre>
--end example] --end note]

<p>A type of either form is a <i>function type</i>*.</u>
<blockquote>[Footnote:
As indicated by the syntax,
cv-qualifiers are a significant component in function return types.
--- end foonote]</blockquote>

<h3>8.3.5p9</h3>

...[<i>Note:</i> typedefs <u>and late-specified return types</u> are sometimes convenient when the return type of a function is complex. For example, the function fpif above could have been declared
<pre>
  typedef int IFUNC(int);
  IFUNC* fpif(int);
</pre>
<u>or
<pre>
  auto fpif(int)->int(*)(int)
</pre>
A late-specified return type is most useful for a type that would be more
complicated to specify before the <i>declarator-id</i>:
<pre>
  template &lt;class T, class U&gt; auto add(T t, U u) -> decltype(t+u);
</pre>
rather than
<pre>
  template &lt;class T, class U&gt; decltype((*(T*)0)+(*(U*)0)) add(T t, U u);
</pre>
</u>-- end note ]

</body>
</html>
