<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 2059</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="2059"></A><H4>2059.
  
Linkage and deduced return types
</H4>
<B>Section: </B>9.2.9.7&#160; [<A href="https://wg21.link/dcl.spec.auto">dcl.spec.auto</A>]
 &#160;&#160;&#160;

 <B>Status: </B>CD5
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2014-12-15<BR>


<P>[Accepted as a DR at the March, 2018 (Jacksonville) meeting.]</P>



<P>Use of function return type deduction makes it possible to
define functions whose return type is a type without linkage.
Although 6.7 [<A href="https://wg21.link/basic.link#8">basic.link</A>] paragraph 8 permits such a
usage if the function is defined in the same translation unit
as it is used, it may be helpful to consider changing the overall
rules regarding the use of types with internal or no linkage.
As an example, the following example permits access to a local
static variable that has not been initialized:</P>

<PRE>
  auto f() {
    static int n = 123;
    struct X { int &amp;f() { return n; } };
    return X();
  }
  int &amp;r = decltype(f())().f();
</PRE>

<P><B>Notes from the February, 2016 meeting:</B></P>

<P>CWG agreed that the current rule in
6.7 [<A href="https://wg21.link/basic.link#8">basic.link</A>] paragraph 8 is unneeded; the ODR
already prohibits use of an entity that is not defined in
the current translation unit and cannot be defined in a
different translation unit.</P>

<P><B>Proposed resolution (November, 2017)</B></P>

<P>Change 6.7 [<A href="https://wg21.link/basic.link#8">basic.link</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>...<DEL>A type without linkage shall not be used as the type of a
variable or function with external linkage unless</DEL>
</P>

<UL>
<LI><P><DEL>the entity has C language linkage
(9.12 [<A href="https://wg21.link/dcl.link">dcl.link</A>]), or</DEL></P></LI>

<LI><P><DEL>the entity is declared within an unnamed namespace
(9.9.2 [<A href="https://wg21.link/namespace.def">namespace.def</A>]), or</DEL></P></LI>

<LI><P><DEL>the entity is not odr-used (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]) or is
defined in the same translation unit.</DEL></P></LI>

</UL>

<P>[<I>Note:</I> In other words, a type without linkage contains a class or
enumeration that cannot be named outside its translation unit. <DEL>An
entity with external linkage declared using such a type could not
correspond to any other entity in another translation unit of the program
and thus must be defined in the translation unit if it is odr-used. Also
note that classes</DEL> <INS>Classes</INS> with linkage may contain members
whose types do not have linkage<DEL>, and that typedef</DEL><INS>.
Typedef</INS> names are ignored in the determination of whether a type has
linkage. &#8212;<I>end note</I>] [<I>Example:</I>
</P>

<PRE>
  template &lt;class T&gt; struct B {
    void g(T) { }
    void h(T);
    friend void i(B, T) { }
  };

  void f() {
    struct A { int x; };  //<SPAN CLASS="cmnt"> no linkage</SPAN>
    A a = { 1 };
    B&lt;A&gt; ba;              //<SPAN CLASS="cmnt"> declares </SPAN>B&lt;A&gt;::g(A)<SPAN CLASS="cmnt"> and </SPAN>B&lt;A&gt;::h(A)
    ba.g(a);              //<SPAN CLASS="cmnt"> OK</SPAN>
    ba.h(a);              //<SPAN CLASS="cmnt"> error: </SPAN>B&lt;A&gt;::h(A)<SPAN CLASS="cmnt"> not defined<INS>; </INS></SPAN><INS>A</INS><SPAN CLASS="cmnt"><INS> cannot be named</INS> in <DEL>the</DEL> <INS>another</INS> translation unit</SPAN>
    i(ba, a);             //<SPAN CLASS="cmnt"> OK</SPAN>
  }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR>
</BODY>
</HTML>
