<?xml version="1.0" encoding="utf-8" ?>
<!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" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.12: http://docutils.sourceforge.net/" />
<title>Allow Attributes on Template Explicit Instantiations</title>
<meta name="date" content="2016-08-23" />
<meta name="author" content="Matthew Woehlke (mwoehlke.floss&#64;gmail.com)" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="allow-attributes-on-template-explicit-instantiations">
<h1 class="title">Allow Attributes on Template Explicit Instantiations</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">Document:</th><td class="field-body">P0537R0</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2016-08-23</td></tr>
<tr class="field"><th class="docinfo-name">Project:</th><td class="field-body">ISO/IEC JTC1 SC22 WG21 Programming Language C++</td>
</tr>
<tr class="field"><th class="docinfo-name">Audience:</th><td class="field-body">Evolution Working Group</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Matthew Woehlke (<a class="reference external" href="mailto:mwoehlke.floss&#64;gmail.com">mwoehlke.floss&#64;gmail.com</a>)</td></tr>
</tbody>
</table>
<style>
  html { color: black; background: white; }
  table.docinfo { margin: 2em 0; }
  p, li { text-align: justify; }
  .literal-block { background: #eee; border: 1px solid #ddd; padding: 0.5em; }
  .addition { color: #2c2; text-decoration: underline; }
  .removal { color: #e22; text-decoration: line-through; }
  .literal-block .literal-block { background: none; border: none; }
  .block-addition { background: #cfc; text-decoration: underline; }
</style><div class="section" id="abstract">
<h1><a class="toc-backref" href="#id1">Abstract</a></h1>
<p>This proposal recommends to remove the prohibition against attributes on a template explicit instantiation.</p>
<p>(Note: references made to the existing draft standard are made against <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf">N4606</a>.)</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#abstract" id="id1">Abstract</a></li>
<li><a class="reference internal" href="#problem" id="id2">Problem</a></li>
<li><a class="reference internal" href="#proposal" id="id3">Proposal</a></li>
<li><a class="reference internal" href="#proposed-wording" id="id4">Proposed Wording</a></li>
<li><a class="reference internal" href="#implementation" id="id5">Implementation</a></li>
<li><a class="reference internal" href="#acknowledgments" id="id6">Acknowledgments</a></li>
<li><a class="reference internal" href="#references" id="id7">References</a></li>
</ul>
</div>
</div>
<div class="section" id="problem">
<h1><a class="toc-backref" href="#id2">Problem</a></h1>
<p>When creating a C++ library, it is typically necessary to annotate in some manner those functions which should be made available to consumers of the library (as opposed to being internal to the library itself). On Windows, this takes the form of <tt class="docutils literal">__declspec(dllexport)</tt>. On ELF platforms, when using hidden visibility, this may look like <tt class="docutils literal"><span class="pre">__attribute__((visibility(&quot;default&quot;)))</span></tt>. Since the proper decoration is dependent on multiple factors — target platform being the most obvious, but in the case of <tt class="docutils literal">__declspec</tt>, the decoration must differ depending on whether the library is being built or consumed — most libraries will define a preprocessor &quot;export decoration symbol&quot; to simplify 'decorating' functions to be exported.</p>
<p>Combined with templates, where the definition of a template function may be internal, but certain instantiations need to be made available to users of the library, one can image code like so:</p>
<pre class="code c++ literal-block">
<span class="comment single">// A template function
</span><span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">T</span><span class="operator">&gt;</span> <span class="name">T</span> <span class="name">foo</span><span class="punctuation">(</span><span class="name">T</span><span class="operator">*</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
  <span class="comment single">// ...
</span><span class="punctuation">}</span>

<span class="comment single">// An exported explicit instantiation
</span><span class="keyword">template</span> <span class="name">FOO_EXPORT</span> <span class="keyword type">int</span> <span class="name">foo</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="operator">*</span><span class="punctuation">);</span>
</pre>
<p>Since attributes were introduced in C++11, there has been activity toward standardizing the mechanisms for export decoration. In particular, GCC and Clang support the use of <tt class="docutils literal"><span class="pre">[[gnu::visibility(&quot;default&quot;)]]</span></tt> as a replacement for <tt class="docutils literal"><span class="pre">__attribute__((visibility(&quot;default&quot;)))</span></tt>. This is an obvious improvement: it is shorter to write, and compilers that don't understand the C++11 attribute may ignore it, rather than raising a syntax error as would be the case if the old form were used with a compiler that does not support it.</p>
<p>Astute readers may have spotted the problem by now: <em>explicit instantiations forbid attributes</em> ([<a class="reference external" href="http://wg21.link/n4606#subsection.7.6.1">dcl.attr.grammar</a>]¶5). This means that the above example cannot use a C++11 attribute on a conforming compiler; indeed, there is no way to write strictly conforming code that also specifies that the instantiation should be exported.</p>
</div>
<div class="section" id="proposal">
<h1><a class="toc-backref" href="#id3">Proposal</a></h1>
<p>Presently, C++ forbids attributes on template explicit instantiations. We suspect that this limitation was imposed in the belief that there are no reasonable attributes that might be applied to such. However, as we have shown above, this is not the case.</p>
<p>We propose to remove this restriction. The standard already allows that an unreasonable attribute may be rejected, so this change by itself does not introduce the ability to do undesirable things. However, it would add freedom to compiler vendors, by allowing them to accept reasonable attributes (e.g. vendor-specific attributes such as export annotation) applied to explicit instantiations. In particular, this change addresses an issue which prevents authors from fully switching to C++11 attributes for export decoration.</p>
<p>We believe that the utility of this change is self evident, as exemplified above, and that it matches programmer expectations. We are also not aware of any serious reasons for the restriction to exist.</p>
</div>
<div class="section" id="proposed-wording">
<h1><a class="toc-backref" href="#id4">Proposed Wording</a></h1>
<p>(Proposed changes are specified relative to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf">N4606</a>.)</p>
<p>In [<a class="reference external" href="http://wg21.link/n4606#subsection.7.6.1">dcl.attr.grammar</a>]¶5, make the following change:</p>
<div class="literal-block compound">
<p>Each <em>attribute-specifier-seq</em> is said to <em>appertain</em> to some entity or statement, identified by the syntactic context where it appears (Clause 6, Clause 7, Clause 8).
If an <em>attribute-specifier-seq</em> that appertains to some entity or statement contains an <em>attribute</em> that is not allowed to apply to that entity or statement, the program is ill-formed.
If an <em>attribute-specifier-seq</em> appertains to a friend declaration (11.3), that declaration shall be a definition. <span class="removal">No *attribute-specifier-seq* shall appertain to an explicit instantiation (14.7.2).</span></p>
</div>
</div>
<div class="section" id="implementation">
<h1><a class="toc-backref" href="#id5">Implementation</a></h1>
<p>At least GCC 4.8 and 6.1 (and presumably all intervening versions) do not implement this restriction and allow attributes — at least the <tt class="docutils literal"><span class="pre">gnu::visibility</span></tt> attribute — to be applied to explicit instantiations.</p>
</div>
<div class="section" id="acknowledgments">
<h1><a class="toc-backref" href="#id6">Acknowledgments</a></h1>
<p>We wish to thank Richard Smith for pointing out this prohibition.</p>
</div>
<div class="section" id="references">
<h1><a class="toc-backref" href="#id7">References</a></h1>
<ul>
<li><p class="first"><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf">N4606</a> Working Draft, Standard for Programming Language C++</p>
<p><a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="https://llvm.org/bugs/show_bug.cgi?id=29094">llvm#29094</a> C++11 attributes not accepted in template explicit instantiation</p>
<p><a class="reference external" href="https://llvm.org/bugs/show_bug.cgi?id=29094">https://llvm.org/bugs/show_bug.cgi?id=29094</a></p>
</li>
</ul>
<!-- .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. -->
<!-- .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. -->
<!-- kate: hl reStructuredText -->
</div>
</div>
</body>
</html>
