<html>

<head>
<title>Remove Deprecated Use of the register Keyword</title>
<style type="text/css">
  p {text-align:justify}
  li {text-align:justify}
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
</style>
</head>

<body>
<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P0001R0</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2015-09-28</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>

<h1>Remove Deprecated Use of the <tt>register</tt> Keyword</tt></h1>

<h2><a name="1.0">I. Table of Contents</a></h2>
<ul>
<li><a href="#1.0">I. Table of Contents</a></li>
<li><a href="#2.0">II. Introduction</a></li>
<li><a href="#3.0">III. Motivation and Scope</a></li>
<li><a href="#4.0">IV. Impact On the Standard</a></li>
<li><a href="#5.0">V. Design Decisions</a></li>
<ul>
  <li><a href="#5.1">Preferred Design</a></li>
  <li><a href="#5.2">Alternative Design 1 (<i>not specified</i>)</a></li>
  <li><a href="#5.3">Alternative Design 2</a></li>
  <li><a href="#5.4">EWG Recommendation</a></li>
</ul>
<li><a href="#6.0">VI. Technical Specification</a></li>
<ul>
  <li><a href="#6.1">2.11 Keywords [lex.key]</a></li>
  <li><a href="#6.2">3.7.3 Automatic storage duration [basic.stc.auto]</a></li>
  <li><a href="#6.3">7.1.1 Storage class specifiers [dcl.stc]</a></li>
  <li><a href="#6.4">7.6.2 Alignment specifier [dcl.align]</a></li>
  <li><a href="#6.5">8.3 Meaning of declarators [dcl.meaning]</a></li>
  <li><a href="#6.6">9.2 Class members [class.mem]</a></li>
  <li><a href="#6.7">A.6 Declarations [gram.dcl]</a></li>
  <li><a href="#6.8">C.4.2 Clause 7: declarations [diff.cpp14.dcl.dcl]</a></li>
  <li><a href="#6.9">D.2 <tt>register</tt> keyword [depr.register]</a></li>
</ul>
<li><a href="#7.0">VII. Acknowledgements</a></li>
<li><a href="#8.0">VIII. References</a></li>
</ul>


<h2><a name="2.0">II. Introduction</a></h2>

<p>
This paper is the first revision of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4340.html">N4340</a>,
which was approved to progress to Core from EWG at the April 2015 Lenexa meeting.

<p>
The <tt>register</tt> keyword was deprecated in the 2011 C++ standard, as its effect was already
implicit in the language.  It remains reserved for future use by the standard, and is time to
remove its vestigial specification.
</p>

<h2><a name="3.0">III. Motivation and Scope</a></h2>

<p>
One theme of C++17 appears to be cleaning up older features, such as trigraphs
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4086">N4086</a>),
<tt>operator++(bool)</tt>
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4192.html#1653">Core issue 1653</a>),
<tt>auto_ptr</tt> and the deprecated adaptable library function API
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190">N4190</a>).
The <tt>register</tt> keyword has no normative function, yet occupies a place in the grammar
that must be specified, so seems a good candidate for similar cleanup.
</p>

<p>
The <tt>register</tt> keyword was deprecated in the 2011 C++ standard in order to preserve
our ability to repurpose a useful English keyword in future proposals, much as <tt>auto</tt>
was repurposed in C++11.  Its usage was deprecated, rather than removed, at the time as
there was no conflicting immediate need for a proposed re-use at the time, unlike with
<tt>auto</tt>.  Similarly, the meaning of the <tt>export</tt> keyword was simply removed
in C++11 due to implementation difficulty and a general lack of compilers implementing
the feature.  It was deemed appropriate to be more conservative with the widely implemented
<tt>register</tt> keyword.  However, users will have seen two standards published with
the keyword deprecated, and with the general theme of clean-up occurring in C++17, should
expect this advertised (potential) removal to finally occur.
</p>

<p>
One reason to consider retaining the keyword is compatibility with the C language.
In particular, the <tt>register</tt> keyword can appear in a function parameter
list.  However, this usage has no meaning in C++, which may be problematic if calling
into C code that ascribes a specific meaning to this hint.
</p>
<p>
However, C has further restrictions on <tt>register</tt> that do not translate to C++, that
would impact only inline function definitions in shared headers.  Code is ill-formed in C if
it tries to take the address of a variable with the <tt>register</tt> <i>storage-class-specifier</i>.
If an array is declared with the <tt>register</tt> <i>storage-class-specifier</i> in C, then
it is undefined behavior to trigger array-to-pointer decay on that array.
</p>
<p>
Another comparison with C is the use of C99  keyword <tt>restrict</tt> in specifying interfaces.
This seems much more widespread than the use of <tt>register</tt>, and has not proved to be a
serious compatibility problem in the following 15 years.
</p>
<p>
Rather than try to resolve the differences with C, this paper prefers to remove the
otherwise redundant feature from C++17.
</p>

<h2><a name="4.0">IV. Impact On the Standard</a></h2>

<p>
The impact on the standard is minimal.  The keyword is specified to be valid in a couple
of places in the grammar, but explicitly has no meaning when used.  It can safely be
removed without impacting the integrity of the standard.
</p>
<p>
Looking beyond the standard: most of the early feedback to this paper has been that there
appears, anecdotally, to be minimal use of the deprecated <tt>register</tt> keyword but
considerably more use of the gcc extension based on this keyword.  This suggests that future
applications of the keyword may face practical constraints.  Similarly, we should think very
carefully before unreserving the keyword, even if we do not make immediate use of it again
in the standard.
</p>

<h2><a name="5.0">V. Design Decisions</a></h2>

<h3><a name="5.1">Preferred Design</a></h3>
<p>
The purpose in removing the usage of <tt>register</tt> is to preserve the ability to use
this valuable keyword for future proposals, such as modules.  It is therefore retained
as a reserved keyword, with a note on intent, similar to the handling of <tt>export</tt>
in C++11.  All other references to the <tt>register</tt> keyword are removed.
</p>

<h3><a name="5.2">Alternative Design 1 (<i>not specified</i>)</a></h3>
<p>
If interface compatibility with C is important enough to retain that usage, then we
should undeprecate the use of <tt>register</tt> when declaration function parameters,
potentially restricted to parameters of functions declared with <tt>extern &quot;C&quot;</tt>
linkage.
</p>
<p>
We might also consider support for <tt>restrict</tt> as a contextual keyword for
functions declared with <tt>extern &quot;C&quot;</tt> linkage as part of the same
design concern.
</p>
<p>
An updated paper along these lines would continue to advocate the removal of <tt>register</tt>
as a <i>storage-class-specifier</i> for local variables though.
</p>

<h3><a name="5.3">Alternative Design 2</a></h3>

<p>
The other suggestion received while authoring this paper is that it does not go far enough,
and the <tt>register</tt> keyword should be released as an identifier to the user community.
</p>
<p>
<tt>register</tt> is certainly a flexible word offering significant use as both a verb
(popular choice for function names, such as registering with a factory facility) and as
a noun (for variables and class types).
</p>
<p>
If no significant proposal comes forward making use of <tt>register</tt> in the near future,
it would be simple to amend 2.11 to no longer reserve the keyword.  This paper recommends
the more conservative approach for now though, of continuing to reserve a valuable term for
standard use, as it would be difficult to reclaim once released.
</p>

<h3><a name="5.4">EWG Recommendation</a></h3>

<p>
The EWG forwarded this proposal to Core, adopting the preferred diection above, with a poll
in favor:
<table border="1">
  <tr>
    <td>SF</td>
    <td>F</td>
    <td>N</td>
    <td>A</td>
    <td>SA</td>
  </tr>
    <td>7</td>
    <td>10</td>
    <td>3</td>
    <td>2</td>
    <td>1</td>
</table>
</p>

<p>
Design alternative 2 was polled and rejected:
<table border="1">
  <tr>
    <td>SF</td>
    <td>F</td>
    <td>N</td>
    <td>A</td>
    <td>SA</td>
  </tr>
    <td>0</td>
    <td>0</td>
    <td>3</td>
    <td>12</td>
    <td>5</td>
</table>
</p>

<p>
The option to retain and undeprecate the <tt>register</tt> keyword was also polled:
<table border="1">
  <tr>
    <td>SF</td>
    <td>F</td>
    <td>N</td>
    <td>A</td>
    <td>SA</td>
  </tr>
    <td>1</td>
    <td>1</td>
    <td>1</td>
    <td>12</td>
    <td>7</td>
</table>
</p>


<h2><a name="6.0">VI. Technical Specification</a></h2>

<p>
Make the following edits (relative to
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296">n4296</a>)
with <ins>insertions</ins> and <del>removals</del> marked like so:
</p>


<h3><a name="6.1">2.11 Keywords [lex.key]</a></h3>
<p>
1 The identifiers shown in Table 3 are reserved for use as keywords (that is, they are unconditionally
treated as keywords in phase 7) except in an <i>attribute-token</i> (7.6.1)
[ <i>Note:</i> The <tt>export</tt><ins> and <tt>register</tt></ins> keyword<ins>s are</ins><del> is</del>
unused but <del>is</del><ins>are</ins> reserved for future use. <i>— end note</i> ]:
</p>

<h3><a name="6.2">3.7.3 Automatic storage duration [basic.stc.auto]</a></h3>
<p>
1 Block-scope variables <del>explicitly declared <tt>register</tt> or</del> not explicitly declared
<tt>static</tt> or <tt>extern</tt> have <i>automatic storage duration</i>. The storage for these
entities lasts until the block in which they are created exits.
</p>

<h3><a name="6.3">7.1.1 Storage class specifiers [dcl.stc]</a></h3>
<p>
1 The storage class specifiers are
</p>
<pre>
      <i>storage-class-specifier:</i><tt>
            <del>register</del>
            static
            thread_local
            extern
            mutable</tt>
</pre>
<p>
At most one <i>storage-class-specifier</i> shall appear in a given <i>decl-specifier-seq</i>,
except that <tt>thread_local</tt> may appear with <tt>static</tt> or <tt>extern</tt>.
If <tt>thread_local</tt> appears in any declaration of a variable it shall be present in all
declarations of that entity. If a <i>storage-class-specifier</i> appears in a <i>decl-specifier-seq</i>,
there can be no <tt>typedef</tt> specifier in the same <i>decl-specifier-seq</i> and the
<i>init-declarator-list</i> of the declaration shall not be empty (except for an anonymous union declared
in a named namespace or in the global namespace, which shall be declared <tt>static</tt> (9.5)).
The <i>storage-class-specifier</i> applies to the name declared by each <i>init-declarator</i> in the
list and not to any names declared by other specifiers. A <i>storage-class-specifier</i> other than
<tt>thread_local</tt> shall not be specified in an explicit specialization (14.7.3) or an explicit
instantiation (14.7.2) directive.
</p>
<p>
2 <del>The <tt>register</tt> specifier shall be applied only to names of variables declared in a block (6.3)
or to function parameters (8.4). It specifies that the named variable has automatic storage duration (3.7.3).</del>
<ins>[ <i>Note:</i> </ins>A variable declared without a <i>storage-class-specifier</i> at block scope or
declared as a function parameter has automatic storage duration by default <ins>(3.7.3)</ins>.<ins> <i>— end note</i> ]</ins>
</p>
<p><del>
3 A <tt>register</tt> specifier is a hint to the implementation that the variable so declared will be heavily used.
[ <i>Note:</i> The hint can be ignored and in most implementations it will be ignored if the address of the
variable is taken. This use is deprecated (see D.2). <i>— end note</i> ]
</del></p>

<h3><a name="6.4">7.6.2 Alignment specifier [dcl.align]</a></h3>
<p>
1 An <i>alignment-specifier</i> may be applied to a variable or to a class data member,
but it shall not be applied to a bit-field, a function parameter, <ins>or</ins> an
<i>exception-declaration</i> (15.3)<del>, or a variable declared with the <tt>register</tt>
storage class specifier</del>. An <i>alignment-specifier</i> may also be applied to the
declaration or definition of a class (in an <i>elaborated-type-specifier</i> (7.1.6.3)
or <i>class-head</i> (Clause 9), respectively) and to the declaration or definition of an
enumeration (in an <i>opaque-enum-declaration</i> or <i>enum-head</i>, respectively (7.2)).
An <i>alignment-specifier</i> with an ellipsis is a pack expansion (14.5.3).
</p>

<h3><a name="6.5">8.3 Meaning of declarators [dcl.meaning]</a></h3>
<p>
2 A <tt>static</tt>, <tt>thread_local</tt>, <tt>extern</tt>, <del><tt>register</tt>,</del>
<tt>mutable</tt>, <tt>friend</tt>, <tt>inline</tt>, <tt>virtual</tt>, or <tt>typedef</tt>
specifier applies directly to each <i>declarator-id</i> in an <i>init-declarator-list</i>;
the type specified for each <i>declarator-id</i> depends on both the <i>decl-specifier-seq</i>
and its declarator.
</p>

<h3><a name="6.6">9.2 Class members [class.mem]</a></h3>
<p>
5 A member shall not be declared with the <tt>extern</tt><del> or register</del>
<i>storage-class-specifier</i>.  Within a class definition, a member shall not be declared with
the <tt>thread_local</tt> <i>storage-class-specifier</i> unless also declared <tt>static</tt>.
</p>

<h3><a name="6.7">A.6 Declarations [gram.dcl]</a></h3>
<pre>
      <i>storage-class-specifier:</i><tt>
            <del>register</del>
            static
            thread_local
            extern
            mutable</tt>
</pre>

<h3><ins><a name="6.8">C.4.2 Clause 7: declarations [diff.cpp14.dcl.dcl]</a></ins></h3>
<p><ins>7.1.1</ins></p>
<p><ins><b>Change:</b> Remove <tt>register</tt> <i>storage-class-specifier</i>.</ins></p>
<p><ins><b>Rationale:</b> Preserve unused keyword for future revisions of this International Standard.</ins></p>
<p><ins><b>Effect on original feature:</b> A valid C++ 2014 declaration utilizing the
<tt>register</tt> <i>storage-class-specifier</i> is ill-formed in this International Standard.
The specifier can simply be removed to retain the original meaning.</ins></p>

<h3><del><a name="6.9">D.2 <tt>register</tt> keyword [depr.register]</a></del></h3>
<p><del>
1 The use of the <tt>register</tt> keyword as a <i>storage-class-specifier</i> (7.1.1) is deprecated.
</del></p>


<h2><a name="7.0">VII. Acknowledgements</a></h2>

<p>
Thanks for early reviews of this paper, while acknowledging that does not imply endorsing its contents,
by  Alan Bellingham, Bret Brown, John Fletcher, Al Grant, Kevlin Henney, Mike Miller, Nathan Myers, Roger Orr,
Richard Smith, Ville Voutilainen, Jonathan Wakely, and Derek Woolverton.
</p>

<h2><a name="8.0">VIII. References</a></h2>
<ul>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4086">N4086</a> Removing trigraphs??!, Richard Smith</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4168">N4168</a> Removing <tt>auto_ptr</tt>, Billy Baker</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190">N4190</a> Removing <tt>auto_ptr</tt>, <tt>random_shuffle()</tt>, And Old <tt>&lt;functional&gt;</tt> Stuff, Stephan T. Lavavej</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4193.html#809">Core issue 809</a> Deprecation of the <tt>register</tt> keyword</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4192.html#1653">Core issue 1653</a> Removing deprecated increment of <tt>bool</tt></li>
</ul>
</body>

</html>
