Topic: Variable templates and instantiation -- Is this


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Mon, 03 Feb 2014 10:32:51 -0800
Raw View
Scott Prager <splinterofchaos@gmail.com> writes:

| Note: I wasn't sure whether this was best in this forum or "ISO C++
| Standard", so please forgive me if I should have posted there.
|=20
| Given the example, pi, from N3651, is this code well formed?
|=20
| template<typename T>
| constexpr T pi =3D T(3.1415926535897932385);
|=20
| template<typename T>
| auto area( T r ) {
| =C2=A0 =C2=A0 return pi<T> * r * r;
| };
|=20
| int main() {
| =C2=A0 =C2=A0 pi<double>;
| =C2=A0 =C2=A0 float a =3D area(10.f);
| =C2=A0 =C2=A0 return a;
| }

Yes, it is well formed.  pi<T> requests an implicit instantiation of the
definition of pi<float>.  Compiler bug, I suspect.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 3 Feb 2014 12:16:51 -0800
Raw View
--089e013a1b9842b64004f18634ad
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Mon, Feb 3, 2014 at 10:02 AM, Scott Prager <splinterofchaos@gmail.com>wr=
ote:

> Note: I wasn't sure whether this was best in this forum or "ISO C++
> Standard", so please forgive me if I should have posted there.
>
> Given the example, *pi*, from N3651<http://www.google.com/url?sa=3Dt&rct=
=3Dj&q=3D&esrc=3Ds&source=3Dweb&cd=3D1&cad=3Drja&ved=3D0CCYQFjAA&url=3Dhttp=
%3A%2F%2Fisocpp.org%2Ffiles%2Fpapers%2FN3651.pdf&ei=3DisTvUpDzIo6MyAGau4GYC=
g&usg=3DAFQjCNHOwaj3WD33nIpo0eMrc29jjI605w&sig2=3DoMEPanN2jNhlvwAJamkYZA&bv=
m=3Dbv.60444564,d.aWc>,
> is this code well formed?
>
> template<typename T>
> constexpr T pi =3D T(3.1415926535897932385);
>
> template<typename T>
> auto area( T r ) {
>     return pi<T> * r * r;
> };
>
> int main() {
>     pi<double>;
>     float a =3D area(10.f);
>     return a;
> }
>
>
>
> When I compile, clang spits out
>
> test2.cpp:10:11: warning: unused variable 'a' [-Wunused-variable]
>     float a =3D area(10.f);
>           ^
>

The version of the code you provided does not produce this warning.


>
> test2.cpp:2:13: warning: variable 'pi<float>' has internal linkage but is
> not defined
>       [-Wundefined-internal]
> constexpr T pi =3D T(3.1415926535897932385);
>             ^
> test2.cpp:6:12: note: used here
>     return pi<T> * r * r;
>            ^
> 2 warnings generated.
> /tmp/test2-e8896e.o: In function `auto area<float>(float)':
> test2.cpp:(.text._Z4areaIfEDaT_[_Z4areaIfEDaT_]+0xe): undefined reference
> to `_ZL2piIfE'
> clang: error: linker command failed with exit code 1 (use -v to see
> invocation)
> fish: Unknown command "./a.out"
>
>
> The one thing that makes this work is when I add an explicit instantiatio=
n
> for *pi<float>* like so:
>
>     template<> float pi<float> =3D (float)pi<double>;
>
> which seems to defeat the purpose entirely.
>

This was a Clang bug (specifically, it's llvm.org/PR17848), and is now
fixed.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--089e013a1b9842b64004f18634ad
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Feb 3, 2014 at 10:02 AM, Scott Prager <span dir=3D"ltr">&lt;<a href=3D"=
mailto:splinterofchaos@gmail.com" target=3D"_blank">splinterofchaos@gmail.c=
om</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex"><div dir=3D"ltr">Note: I wasn&#39;t sure whether this was =
best in this forum or &quot;ISO C++ Standard&quot;, so please forgive me if=
 I should have posted there.<br>
<br>Given the example, <i>pi</i>, from <a href=3D"http://www.google.com/url=
?sa=3Dt&amp;rct=3Dj&amp;q=3D&amp;esrc=3Ds&amp;source=3Dweb&amp;cd=3D1&amp;c=
ad=3Drja&amp;ved=3D0CCYQFjAA&amp;url=3Dhttp%3A%2F%2Fisocpp.org%2Ffiles%2Fpa=
pers%2FN3651.pdf&amp;ei=3DisTvUpDzIo6MyAGau4GYCg&amp;usg=3DAFQjCNHOwaj3WD33=
nIpo0eMrc29jjI605w&amp;sig2=3DoMEPanN2jNhlvwAJamkYZA&amp;bvm=3Dbv.60444564,=
d.aWc" target=3D"_blank">N3651</a>, is this code well formed?<br>
<br><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(18=
7,187,187);word-wrap:break-word"><code><div><span style=3D"color:rgb(0,0,13=
6)">template</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span st=
yle=3D"color:rgb(0,0,136)">typename</span><span style> T</span><span style=
=3D"color:rgb(102,102,0)">&gt;</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">constexpr</span><span style> T pi=
 </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style> T</span=
><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,10=
2,102)">3.1415926535897932385</span><span style=3D"color:rgb(102,102,0)">);=
</span><span style><br>
<br></span><span style=3D"color:rgb(0,0,136)">template</span><span style=3D=
"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,136)">typena=
me</span><span style> T</span><span style=3D"color:rgb(102,102,0)">&gt;</sp=
an><span style><br>
</span><span style=3D"color:rgb(0,0,136)">auto</span><span style> area</spa=
n><span style=3D"color:rgb(102,102,0)">(</span><span style> T r </span><spa=
n style=3D"color:rgb(102,102,0)">)</span><span style> </span><span style=3D=
"color:rgb(102,102,0)">{</span><span style><br>
&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">return</span><span =
style> pi</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style> </spa=
n><span style=3D"color:rgb(102,102,0)">*</span><span style> r </span><span =
style=3D"color:rgb(102,102,0)">*</span><span style> r</span><span style=3D"=
color:rgb(102,102,0)">;</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">};</span><span style><br><br></=
span><span style=3D"color:rgb(0,0,136)">int</span><span style> main</span><=
span style=3D"color:rgb(102,102,0)">()</span><span style> </span><span styl=
e=3D"color:rgb(102,102,0)">{</span><span style><br>
&nbsp; &nbsp; pi</span><span style=3D"color:rgb(0,136,0)">&lt;double&gt;</s=
pan><span style=3D"color:rgb(102,102,0)">;</span><span style><br>&nbsp; &nb=
sp; </span><span style=3D"color:rgb(0,0,136)">float</span><span style> a </=
span><span style=3D"color:rgb(102,102,0)">=3D</span><span style> area</span=
><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,10=
2,102)">10.f</span><span style=3D"color:rgb(102,102,0)">);</span><span styl=
e><br>
&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">return</span><span =
style> a</span><span style=3D"color:rgb(102,102,0)">;</span><span style><br=
></span><span style=3D"color:rgb(102,102,0)">}</span><span style><br></span=
></div></code></div>
<br><br><br>When I compile, clang spits out<br><div style=3D"background-col=
or:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word"=
><code><div><span style><br>test2</span><span style=3D"color:rgb(102,102,0)=
">.</span><span style>cpp</span><span style=3D"color:rgb(102,102,0)">:</spa=
n><span style=3D"color:rgb(0,102,102)">10</span><span style=3D"color:rgb(10=
2,102,0)">:</span><span style=3D"color:rgb(0,102,102)">11</span><span style=
=3D"color:rgb(102,102,0)">:</span><span style> warning</span><span style=3D=
"color:rgb(102,102,0)">:</span><span style> unused variable </span><span st=
yle=3D"color:rgb(0,136,0)">&#39;a&#39;</span><span style> </span><span styl=
e=3D"color:rgb(102,102,0)">[-</span><span style=3D"color:rgb(102,0,102)">Wu=
nused</span><span style=3D"color:rgb(102,102,0)">-</span><span style>variab=
le</span><span style=3D"color:rgb(102,102,0)">]</span><span style><br>
&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">float</span><span s=
tyle> a </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style> =
area</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"colo=
r:rgb(0,102,102)">10.f</span><span style=3D"color:rgb(102,102,0)">);</span>=
<span style><br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:rgb(102,102,=
0)">^</span></div></code></div></div></blockquote><div><br></div><div>The v=
ersion of the code you provided does not produce this warning.</div><div>&n=
bsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-sty=
le:solid;padding-left:1ex">
<div dir=3D"ltr"><div style=3D"background-color:rgb(250,250,250);border:1px=
 solid rgb(187,187,187);word-wrap:break-word"><code><div><span style><br>te=
st2</span><span style=3D"color:rgb(102,102,0)">.</span><span style>cpp</spa=
n><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,1=
02,102)">2</span><span style=3D"color:rgb(102,102,0)">:</span><span style=
=3D"color:rgb(0,102,102)">13</span><span style=3D"color:rgb(102,102,0)">:</=
span><span style> warning</span><span style=3D"color:rgb(102,102,0)">:</spa=
n><span style> variable </span><span style=3D"color:rgb(0,136,0)">&#39;pi&l=
t;float&gt;&#39;</span><span style> has </span><span style=3D"color:rgb(0,0=
,136)">internal</span><span style> linkage but </span><span style=3D"color:=
rgb(0,0,136)">is</span><span style> </span><span style=3D"color:rgb(0,0,136=
)">not</span><span style> </span><span style=3D"color:rgb(0,0,136)">defined=
</span><span style><br>
&nbsp; &nbsp; &nbsp; </span><span style=3D"color:rgb(102,102,0)">[-</span><=
span style=3D"color:rgb(102,0,102)">Wundefined</span><span style=3D"color:r=
gb(102,102,0)">-</span><span style=3D"color:rgb(0,0,136)">internal</span><s=
pan style=3D"color:rgb(102,102,0)">]</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">constexpr</span><span style> T pi=
 </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style> T</span=
><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,10=
2,102)">3.1415926535897932385</span><span style=3D"color:rgb(102,102,0)">);=
</span><span style><br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:rgb(1=
02,102,0)">^</span><span style><br>test2</span><span style=3D"color:rgb(102=
,102,0)">.</span><span style>cpp</span><span style=3D"color:rgb(102,102,0)"=
>:</span><span style=3D"color:rgb(0,102,102)">6</span><span style=3D"color:=
rgb(102,102,0)">:</span><span style=3D"color:rgb(0,102,102)">12</span><span=
 style=3D"color:rgb(102,102,0)">:</span><span style> note</span><span style=
=3D"color:rgb(102,102,0)">:</span><span style> used here<br>
&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">return</span><span =
style> pi</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style> </spa=
n><span style=3D"color:rgb(102,102,0)">*</span><span style> r </span><span =
style=3D"color:rgb(102,102,0)">*</span><span style> r</span><span style=3D"=
color:rgb(102,102,0)">;</span><span style><br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:rgb(10=
2,102,0)">^</span><span style><br></span><span style=3D"color:rgb(0,102,102=
)">2</span><span style> warnings generated</span><span style=3D"color:rgb(1=
02,102,0)">.</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">/</span><span style>tmp</span><=
span style=3D"color:rgb(102,102,0)">/</span><span style>test2</span><span s=
tyle=3D"color:rgb(102,102,0)">-</span><span style>e8896e</span><span style=
=3D"color:rgb(102,102,0)">.</span><span style>o</span><span style=3D"color:=
rgb(102,102,0)">:</span><span style> </span><span style=3D"color:rgb(102,0,=
102)">In</span><span style> </span><span style=3D"color:rgb(0,0,136)">funct=
ion</span><span style> </span><span style=3D"color:rgb(0,136,0)">`auto area=
&lt;float&gt;(float)&#39;:<br>
test2.cpp:(.text._Z4areaIfEDaT_[_Z4areaIfEDaT_]+0xe): undefined reference t=
o `</span><span style>_ZL2piIfE</span><span style=3D"color:rgb(0,136,0)">&#=
39;<br>clang: error: linker command failed with exit code 1 (use -v to see =
invocation)<br>
fish: Unknown command &ldquo;./a.out&rdquo;<br><br></span></div></code></di=
v><br>The one thing that makes this work is when I add an explicit instanti=
ation for <i>pi&lt;float&gt;</i> like so:<br><br>&nbsp;&nbsp;&nbsp; templat=
e&lt;&gt; float pi&lt;float&gt; =3D (float)pi&lt;double&gt;;<br>
<br>which seems to defeat the purpose entirely.<br></div></blockquote><div>=
<br></div><div>This was a Clang bug (specifically, it&#39;s <a href=3D"http=
://llvm.org/PR17848">llvm.org/PR17848</a>), and is now fixed.</div></div>
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e013a1b9842b64004f18634ad--

.


Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Tue, 4 Feb 2014 08:15:02 +0100
Raw View
2014-02-03 Scott Prager <splinterofchaos@gmail.com>:
> Note: I wasn't sure whether this was best in this forum or "ISO C++
> Standard", so please forgive me if I should have posted there.
>
> Given the example, pi, from N3651, is this code well formed?
>
> template<typename T>
> constexpr T pi = T(3.1415926535897932385);
>
> template<typename T>
> auto area( T r ) {
>     return pi<T> * r * r;
> };
>
> int main() {
>     pi<double>;
>     float a = area(10.f);
>     return a;
> }
>
>

Just be sure that you don't take the address of `pi<T>` in functions
with external linkage such as `area`. For instantiations of the
primary definition of `pi<T>`, this usually results in undefined
behavior.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: potswa@gmail.com
Date: Tue, 4 Feb 2014 15:32:19 +0800
Raw View
On Feb 4, 2014, at 3:15 PM, Johannes Schaub <schaub.johannes@googlemail.com=
> wrote:

> Just be sure that you don't take the address of `pi<T>` in functions
> with external linkage such as `area`. For instantiations of the
> primary definition of `pi<T>`, this usually results in undefined
> behavior.

That's easier said than done. A variable template specialization then canno=
t be passed by const reference, and if it is of literal type, cannot be pas=
sed by value either but can only directly form member access expressions.

My impression had been that variable templates were just syntactic sugar fo=
r a class with a single static data member. Reviewing now, static data memb=
ers of class templates have an exception to the ODR rule but variable templ=
ates do not. (Putting a variable template in a header at all currently appe=
ars to be illegal!)

Reading N3651 now, I'm very surprised. It only talks about constexpr object=
s, and its motivation section only discusses constants. But the feature is =
far more sweeping. For non-constants, it's completely broken if specializat=
ions in different TUs don't name the same object.

I think the standardese needs to be taken with a grain of salt, a bit like =
alias templates. There's no reason for variable template instantiations to =
have an identity crisis where class template static data members don't. The=
 absence of specification here is not intended to be specification of absen=
ce.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: potswa@gmail.com
Date: Tue, 4 Feb 2014 15:33:27 +0800
Raw View
--Apple-Mail=_D984E2FC-D831-473E-95F9-D7A63BEF8348
Content-Type: text/plain; charset=ISO-8859-1


On Feb 4, 2014, at 3:32 PM, potswa@gmail.com wrote:

> and if it is of literal type, cannot be passed by value either but can only directly form member access expressions.

Of course, I mean literal class type.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--Apple-Mail=_D984E2FC-D831-473E-95F9-D7A63BEF8348
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 4=
, 2014, at 3:32 PM, <a href=3D"mailto:potswa@gmail.com">potswa@gmail.com</a=
> wrote:</div><br class=3D"Apple-interchange-newline"><blockquote type=3D"c=
ite">and if it is of literal type, cannot be passed by value either but can=
 only directly form member access expressions.<br></blockquote></div><br><d=
iv>Of course, I mean literal <i>class</i>&nbsp;type.</div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_D984E2FC-D831-473E-95F9-D7A63BEF8348--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Tue, 04 Feb 2014 09:14:17 -0800
Raw View
Johannes Schaub <schaub.johannes@googlemail.com> writes:

| 2014-02-03 Scott Prager <splinterofchaos@gmail.com>:
| > Note: I wasn't sure whether this was best in this forum or "ISO C++
| > Standard", so please forgive me if I should have posted there.
| >
| > Given the example, pi, from N3651, is this code well formed?
| >
| > template<typename T>
| > constexpr T pi = T(3.1415926535897932385);
| >
| > template<typename T>
| > auto area( T r ) {
| >     return pi<T> * r * r;
| > };
| >
| > int main() {
| >     pi<double>;
| >     float a = area(10.f);
| >     return a;
| > }
| >
| >
|
| Just be sure that you don't take the address of `pi<T>` in functions
| with external linkage such as `area`. For instantiations of the
| primary definition of `pi<T>`, this usually results in undefined
| behavior.

Huh, that is needlessly alarming; let's keep in proportion.

-- Gaby

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 4 Feb 2014 11:23:59 -0800
Raw View
--20cf307f37660e42af04f1999593
Content-Type: text/plain; charset=ISO-8859-1

On Mon, Feb 3, 2014 at 11:32 PM, <potswa@gmail.com> wrote:

>
> On Feb 4, 2014, at 3:15 PM, Johannes Schaub <
> schaub.johannes@googlemail.com> wrote:
>
> > Just be sure that you don't take the address of `pi<T>` in functions
> > with external linkage such as `area`. For instantiations of the
> > primary definition of `pi<T>`, this usually results in undefined
> > behavior.
>
> That's easier said than done. A variable template specialization then
> cannot be passed by const reference, and if it is of literal type, cannot
> be passed by value either but can only directly form member access
> expressions.
>

The problem that pi<T> has internal linkage is easily avoided:

  template<typename T>
  extern constexpr T pi = T(3.1415926535897932385);

Also, the problem would only have arisen if we used the address of pi<T> in
an inline function or a template, so it's not as scary as it seems (and
using a constexpr variable for its address rather than its value is a
little unusual in any case).

My impression had been that variable templates were just syntactic sugar
> for a class with a single static data member. Reviewing now, static data
> members of class templates have an exception to the ODR rule but variable
> templates do not. (Putting a variable template in a header at all currently
> appears to be illegal!)
>

I agree that [basic.def.odr]p6 should apply to variable templates (and
currently does not). I think the consequence of this is that the same
variable template can have different definitions in different TUs, not that
it can't be defined in multiple TUs, but either way, that's the wrong rule.
I've forwarded this to Mike as a core issue.


> Reading N3651 now, I'm very surprised. It only talks about constexpr
> objects, and its motivation section only discusses constants. But the
> feature is far more sweeping. For non-constants, it's completely broken if
> specializations in different TUs don't name the same object.


The wording for a significant feature isn't likely to be perfect the first
time around =)

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--20cf307f37660e42af04f1999593
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Feb 3, 2014 at 11:32 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:potsw=
a@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex">
<div class=3D"im"><br>
On Feb 4, 2014, at 3:15 PM, Johannes Schaub &lt;<a href=3D"mailto:schaub.jo=
hannes@googlemail.com">schaub.johannes@googlemail.com</a>&gt; wrote:<br>
<br>
&gt; Just be sure that you don&#39;t take the address of `pi&lt;T&gt;` in f=
unctions<br>
&gt; with external linkage such as `area`. For instantiations of the<br>
&gt; primary definition of `pi&lt;T&gt;`, this usually results in undefined=
<br>
&gt; behavior.<br>
<br>
</div>That&#39;s easier said than done. A variable template specialization =
then cannot be passed by const reference, and if it is of literal type, can=
not be passed by value either but can only directly form member access expr=
essions.<br>
</blockquote><div><br></div><div>The problem that pi&lt;T&gt; has internal =
linkage is easily avoided:</div><div><br></div><div>=A0 template&lt;typenam=
e T&gt;</div><div>=A0 extern constexpr T pi =3D T(3.1415926535897932385);</=
div>
<div>=A0</div><div>Also, the problem would only have arisen if we used the =
address of pi&lt;T&gt; in an inline function or a template, so it&#39;s not=
 as scary as it seems (and using a constexpr variable for its address rathe=
r than its value is a little unusual in any case).</div>
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex">
My impression had been that variable templates were just syntactic sugar fo=
r a class with a single static data member. Reviewing now, static data memb=
ers of class templates have an exception to the ODR rule but variable templ=
ates do not. (Putting a variable template in a header at all currently appe=
ars to be illegal!)<br>
</blockquote><div><br></div><div>I agree that [basic.def.odr]p6 should appl=
y to variable templates (and currently does not). I think the consequence o=
f this is that the same variable template can have different definitions in=
 different TUs, not that it can&#39;t be defined in multiple TUs, but eithe=
r way, that&#39;s the wrong rule. I&#39;ve forwarded this to Mike as a core=
 issue.</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex">
Reading N3651 now, I&#39;m very surprised. It only talks about constexpr ob=
jects, and its motivation section only discusses constants. But the feature=
 is far more sweeping. For non-constants, it&#39;s completely broken if spe=
cializations in different TUs don&#39;t name the same object.</blockquote>
<div><br></div><div>The wording for a significant feature isn&#39;t likely =
to be perfect the first time around =3D)</div></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--20cf307f37660e42af04f1999593--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Tue, 04 Feb 2014 11:50:42 -0800
Raw View
Richard Smith <richard@metafoo.co.uk> writes:

| On Mon, Feb 3, 2014 at 11:32 PM, <potswa@gmail.com> wrote:
|=20
|    =20
|     On Feb 4, 2014, at 3:15 PM, Johannes Schaub
|     <schaub.johannes@googlemail.com> wrote:
|    =20
|     > Just be sure that you don't take the address of `pi<T>` in
|     functions
|     > with external linkage such as `area`. For instantiations of the
|     > primary definition of `pi<T>`, this usually results in undefined
|     > behavior.
|    =20
|    =20
|     That's easier said than done. A variable template specialization
|     then cannot be passed by const reference, and if it is of literal
|     type, cannot be passed by value either but can only directly form
|     member access expressions.
|    =20
|=20
| The problem that pi<T> has internal linkage is easily avoided:
|=20
| =C2=A0 template<typename T>
| =C2=A0 extern constexpr T pi =3D T(3.1415926535897932385);
| =C2=A0
| Also, the problem would only have arisen if we used the address of
| pi<T> in an inline function or a template, so it's not as scary as it
| seems (and using a constexpr variable for its address rather than its
| value is a little unusual in any case).

And even in those cases, it shouldn't be a problem if the template is
defined and instantiated in the same and only one translation unit --
similar for inline functions.

|     My impression had been that variable templates were just syntactic
|     sugar for a class with a single static data member. Reviewing now,
|     static data members of class templates have an exception to the
|     ODR rule but variable templates do not. (Putting a variable
|     template in a header at all currently appears to be illegal!)
|=20
| I agree that [basic.def.odr]p6 should apply to variable templates (and
| currently does not). I think the consequence of this is that the same
| variable template can have different definitions in different TUs, not
| that it can't be defined in multiple TUs, but either way, that's the
| wrong rule. I've forwarded this to Mike as a core issue.

static data members of class templates have external linkage; const(expr)
variables have internal linkage by default and I think we want to keep
that when they result from template instantiations; so we end up
with internal-to-vague linkage (we don't have the term "vague" linkage
in the standards text) which by ODR means a variable template definition
would follow the same token-wise equivalence we require of any other
templates and inline functions.   Address uniqueness for instantiations
is same for non-template const(expr) variables.

|     Reading N3651 now, I'm very surprised. It only talks about
|     constexpr objects, and its motivation section only discusses
|     constants. But the feature is far more sweeping. For
|     non-constants, it's completely broken if specializations in
|     different TUs don't name the same object.
|=20
|=20
| The wording for a significant feature isn't likely to be perfect the
| first time around =3D)

especially when going from const(expr) objects (the primary motivation)
to non-const objects as requested by EWG :-)

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: potswa@gmail.com
Date: Wed, 5 Feb 2014 08:55:47 +0800
Raw View
--Apple-Mail=_2626516F-1E6B-420E-AE8E-64E3C04B518A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 5, 2014, at 3:23 AM, Richard Smith <richard@metafoo.co.uk> wrote:

> The problem that pi<T> has internal linkage is easily avoided:
>=20
>   template<typename T>
>   extern constexpr T pi =3D T(3.1415926535897932385);

extern constexpr itself is broken. You cannot define an extern object in tw=
o TUs but must define a constexpr object in every TU. I've mentioned it her=
e before and intend to submit a proposal about this.

Hmm, come to think of it, function templates of static linkage are supporte=
d, so it would seem to be wrong to force variable templates to have extern =
linkage. Const-qualified and constexpr objects get static linkage by defaul=
t so the extern will be needed even after fixing the ODR, unless we make de=
fault linkage even less consistent.

> Also, the problem would only have arisen if we used the address of pi<T> =
in an inline function or a template, so it's not as scary as it seems

Header libraries do almost everything in such a context.

> (and using a constexpr variable for its address rather than its value is =
a little unusual in any case).

But it happens unintentionally when passing to a parameter of const & or cl=
ass type.

> My impression had been that variable templates were just syntactic sugar =
for a class with a single static data member. Reviewing now, static data me=
mbers of class templates have an exception to the ODR rule but variable tem=
plates do not. (Putting a variable template in a header at all currently ap=
pears to be illegal!)
>=20
> I agree that [basic.def.odr]p6 should apply to variable templates (and cu=
rrently does not). I think the consequence of this is that the same variabl=
e template can have different definitions in different TUs, not that it can=
't be defined in multiple TUs, but either way, that's the wrong rule. I've =
forwarded this to Mike as a core issue.

I prefer to think in terms of linkage -- whether it's the same object in ev=
ery TU.

Constexpr objects should have a definition in each TU, regardless of templa=
ting or linkage. Non-trivially constructible objects must be defined in onl=
y one TU to have a well-defined static initialization order, a requirement =
following from linkage which is unaffected by templating.

So I'm leaning toward thinking now that templates are a red herring, and th=
e entire problem is extern constexpr.

>=20
> Reading N3651 now, I'm very surprised. It only talks about constexpr obje=
cts, and its motivation section only discusses constants. But the feature i=
s far more sweeping. For non-constants, it's completely broken if specializ=
ations in different TUs don't name the same object.
>=20
> The wording for a significant feature isn't likely to be perfect the firs=
t time around =3D)

What kind of quality is C++14 aiming for? Will it pass the ballot because c=
onsensus of intent is clear in the minds of those voting?

I feel vehemently that the normative text of the standard is the only autho=
rity that people can really access, but on the other hand we do have to get=
 it out the door, and the sooner that happens the sooner the next standard =
(hopefully C++17) will be available as well. Being February now, it seems t=
he risk of slipping to C++15 is already non-negligible.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_2626516F-1E6B-420E-AE8E-64E3C04B518A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 5=
, 2014, at 3:23 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafoo.co.=
uk">richard@metafoo.co.uk</a>&gt; wrote:</div><br class=3D"Apple-interchang=
e-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_e=
xtra"><div class=3D"gmail_quote"><div>The problem that pi&lt;T&gt; has inte=
rnal linkage is easily avoided:</div><div><br></div><div>&nbsp; template&lt=
;typename T&gt;</div><div>&nbsp; extern constexpr T pi =3D T(3.141592653589=
7932385);</div></div></div></div></blockquote><div><br></div><div><font fac=
e=3D"Courier">extern constexpr</font> itself is broken. You cannot define a=
n extern object in two TUs but must define a constexpr object in every TU. =
I&rsquo;ve mentioned it here before and intend to submit a proposal about t=
his.</div><div><br></div><div>Hmm, come to think of it, function templates =
of static linkage are supported, so it would seem to be wrong to force vari=
able templates to have extern linkage. Const-qualified and constexpr object=
s get static linkage by default so the extern will be needed even after fix=
ing the ODR, unless we make default linkage even less consistent.</div><br>=
<blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div =
class=3D"gmail_quote">
<div>Also, the problem would only have arisen if we used the address of pi&=
lt;T&gt; in an inline function or a template, so it's not as scary as it se=
ems </div></div></div></div></blockquote><div><br></div><div>Header librari=
es do almost everything in such a context.</div><br><blockquote type=3D"cit=
e"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><=
div>(and using a constexpr variable for its address rather than its value i=
s a little unusual in any case).</div></div></div></div></blockquote><div><=
br></div><div>But it happens unintentionally when passing to a parameter of=
 <font face=3D"Courier">const &amp;</font> or class type.</div><br><blockqu=
ote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D=
"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; borde=
r-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style=
: solid; padding-left: 1ex; position: static; z-index: auto;">
My impression had been that variable templates were just syntactic sugar fo=
r a class with a single static data member. Reviewing now, static data memb=
ers of class templates have an exception to the ODR rule but variable templ=
ates do not. (Putting a variable template in a header at all currently appe=
ars to be illegal!)<br>
</blockquote><div><br></div><div>I agree that [basic.def.odr]p6 should appl=
y to variable templates (and currently does not). I think the consequence o=
f this is that the same variable template can have different definitions in=
 different TUs, not that it can't be defined in multiple TUs, but either wa=
y, that's the wrong rule. I've forwarded this to Mike as a core issue.</div=
></div></div></div></blockquote><div><br></div><div>I prefer to think in te=
rms of linkage &mdash; whether it&rsquo;s the same object in every TU.</div=
><div><br></div><div>Constexpr objects should have a definition in each TU,=
 regardless of templating or linkage. Non-trivially constructible objects m=
ust be defined in only one TU to have a well-defined static initialization =
order, a requirement following from linkage which is unaffected by templati=
ng.</div><div><br></div><div>So I&rsquo;m leaning toward thinking now that =
templates are a red herring, and the entire problem is <font face=3D"Courie=
r">extern constexpr</font>.</div><br><blockquote type=3D"cite"><div dir=3D"=
ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); bo=
rder-left-style: solid; padding-left: 1ex; position: static; z-index: auto;=
">
Reading N3651 now, I'm very surprised. It only talks about constexpr object=
s, and its motivation section only discusses constants. But the feature is =
far more sweeping. For non-constants, it's completely broken if specializat=
ions in different TUs don't name the same object.</blockquote>
<div><br></div><div>The wording for a significant feature isn't likely to b=
e perfect the first time around =3D)</div></div></div></div></blockquote><d=
iv><br></div><div>What kind of quality is C++14 aiming for? Will it pass th=
e ballot because consensus of intent is clear in the minds of those voting?=
</div><div><br></div><div>I feel vehemently that the normative text of the =
standard is the only authority that people can really access, but on the ot=
her hand we do have to get it out the door, and the sooner that happens the=
 sooner the next standard (hopefully C++17) will be available as well. Bein=
g February now, it seems the risk of slipping to C++15 is already non-negli=
gible.</div><div><br></div></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_2626516F-1E6B-420E-AE8E-64E3C04B518A--

.


Author: potswa@gmail.com
Date: Wed, 5 Feb 2014 09:04:30 +0800
Raw View
--Apple-Mail=_A0B87A13-DC53-45F0-9B2D-F5FBCBFAB891
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 5, 2014, at 3:50 AM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> And even in those cases, it shouldn't be a problem if the template is
> defined and instantiated in the same and only one translation unit --
> similar for inline functions.

If the program has only one TU, the problem goes away, along with all of li=
nkage :P

> static data members of class templates have external linkage; const(expr)
> variables have internal linkage by default and I think we want to keep
> that when they result from template instantiations; so we end up
> with internal-to-vague linkage (we don't have the term "vague" linkage
> in the standards text)

Vague linkage is identical to that of inline functions, no?

I agree that constexpr objects should be as such. Unfortunately the concept=
 doesn't extend to dynamic initialization.

> which by ODR means a variable template definition
> would follow the same token-wise equivalence we require of any other
> templates and inline functions.   Address uniqueness for instantiations
> is same for non-template const(expr) variables.

What do you mean by internal-to-vague linkage? Internal linkage means that =
each TU references a different entity from a common name, and vague linkage=
 means that the linker generates a common entity from several definitions. =
The ODR doesn't and cannot apply to objects of internal linkage because the=
y are separate -- that is the purpose of internal linkage.

It would be too surprising if something explicitly defined with static (out=
side a class) were accessible from another TU.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_A0B87A13-DC53-45F0-9B2D-F5FBCBFAB891
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 5=
, 2014, at 3:50 AM, Gabriel Dos Reis &lt;<a href=3D"mailto:gdr@axiomatics.o=
rg">gdr@axiomatics.org</a>&gt; wrote:</div><br class=3D"Apple-interchange-n=
ewline"><blockquote type=3D"cite">And even in those cases, it shouldn't be =
a problem if the template is<br>defined and instantiated in the same and on=
ly one translation unit --<br>similar for inline functions.<br></blockquote=
><div><br></div><div>If the program has only one TU, the problem goes away,=
 along with all of linkage :P</div><br><blockquote type=3D"cite">static dat=
a members of class templates have external linkage; const(expr)<br>variable=
s have internal linkage by default and I think we want to keep<br>that when=
 they result from template instantiations; so we end up<br>with internal-to=
-vague linkage (we don't have the term "vague" linkage<br>in the standards =
text) </blockquote><div><br></div><div>Vague linkage is identical to that o=
f inline functions, no?</div><div><br></div><div>I agree that constexpr obj=
ects should be as such. Unfortunately the concept doesn&rsquo;t extend to d=
ynamic initialization.</div><br><blockquote type=3D"cite">which by ODR mean=
s a variable template definition<br>would follow the same token-wise equiva=
lence we require of any other<br>templates and inline functions. &nbsp;&nbs=
p;Address uniqueness for instantiations<br>is same for non-template const(e=
xpr) variables.<br></blockquote><div><br></div><div>What do you mean by int=
ernal-to-vague linkage? Internal linkage means that each TU references a di=
fferent entity from a common name, and vague linkage means that the linker =
generates a common entity from several definitions. The ODR doesn&rsquo;t a=
nd cannot apply to objects of internal linkage because they are separate &m=
dash; that is the purpose of internal linkage.</div></div><div><br></div><d=
iv>It would be too surprising if something explicitly defined with <font fa=
ce=3D"Courier">static</font> (outside a class) were accessible from another=
 TU.</div><div><br></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_A0B87A13-DC53-45F0-9B2D-F5FBCBFAB891--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Tue, 04 Feb 2014 21:06:22 -0800
Raw View
potswa@gmail.com writes:

[...]

| Hmm, come to think of it, function templates of static linkage are
| supported, so it would seem to be wrong to force variable templates to
| have extern linkage.

Right; which is why this whole subthread does not gain any traction with
me.   Any notion that constexpr variable template would need 'extern' or
can't be mentioned in function templates isn't reasonating.

[...]

| Constexpr objects should have a definition in each TU, regardless of
| templating or linkage.

If they are (odr-)used in that translation unit.

| Non-trivially constructible objects must be defined in only one TU to
| have a well-defined static initialization order, a requirement
| following from linkage which is unaffected by templating.

I consider any notion of 'definition required' predicated on
non-triviality to be brittle - no matter the technical explanation.  So,
I wouldn't go there.

| So I=E2=80=99m leaning toward thinking now that templates are a red herri=
ng,
| and the entire problem is extern constexpr.

If it really is one.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Tue, 04 Feb 2014 21:38:37 -0800
Raw View
potswa@gmail.com writes:

[...]

| If the program has only one TU, the problem goes away, along with all
| of linkage :P
|=20
|     static data members of class templates have external linkage;
|     const(expr)
|     variables have internal linkage by default and I think we want to
|     keep
|     that when they result from template instantiations; so we end up
|     with internal-to-vague linkage (we don't have the term "vague"
|     linkage
|     in the standards text)=20
|=20
|=20
| Vague linkage is identical to that of inline functions, no?

it isn't defined in the standards text.

| I agree that constexpr objects should be as such. Unfortunately the
| concept doesn=E2=80=99t extend to dynamic initialization.

I view linkage and dynamic initialization as orthogonal issues;  why do
you think they intersect here?

|     which by ODR means a variable template definition
|     would follow the same token-wise equivalence we require of any
|     other
|     templates and inline functions. =C2=A0=C2=A0Address uniqueness for
|     instantiations
|     is same for non-template const(expr) variables.
|    =20
|=20
| What do you mean by internal-to-vague linkage? Internal linkage means
| that each TU references a different entity from a common name, and
| vague linkage means that the linker generates a common entity from
| several definitions. The ODR doesn=E2=80=99t and cannot apply to objects =
of
| internal linkage because they are separate =E2=80=94 that is the purpose =
of
| internal linkage.

From a low-level point of view, that is probably correct.  But it
misses the entire point and idea behind ODR.  The ODR idea is that,
ultimately, there is one and only one "abstract" definition of a given
entity; and because of the baroque source file inclusion model inherited
from C, one had to resort to "token wise" equivalence.  The internal
linkage stuff is largely orthogonal and (from what I know) a historical
accident which needed to be taken into account because constants tend to
be prominently present in header files.  Consequently, when looking at
ODR, one should keep that perspective; not just the low-level
(imperfect) implementation we current have in the standards text.=20

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 5 Feb 2014 11:06:40 -0800
Raw View
--089e011847d0ec3fbd04f1ad74db
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Feb 4, 2014 at 4:55 PM, <potswa@gmail.com> wrote:

>
> On Feb 5, 2014, at 3:23 AM, Richard Smith <richard@metafoo.co.uk> wrote:
>
> The problem that pi<T> has internal linkage is easily avoided:
>
>   template<typename T>
>   extern constexpr T pi = T(3.1415926535897932385);
>
>
> extern constexpr itself is broken. You cannot define an extern object in
> two TUs but must define a constexpr object in every TU. I've mentioned it
> here before and intend to submit a proposal about this.
>

extern constexpr isn't broken for variable templates, because notionally
template instantiations are performed once per program, not once per
translation unit, so there's no multiple-definition problem in this case.

For the non-variable-template case, 'inline extern constexpr' semantics
would probably be useful (that is, allow multiple definitions of an extern
constexpr variable, but require them to be equivalent under the ODR, just
as we do for inline functions). I think that's what you're suggesting?


> Hmm, come to think of it, function templates of static linkage are
> supported, so it would seem to be wrong to force variable templates to have
> extern linkage. Const-qualified and constexpr objects get static linkage by
> default so the extern will be needed even after fixing the ODR, unless we
> make default linkage even less consistent.
>
> Also, the problem would only have arisen if we used the address of pi<T>
> in an inline function or a template, so it's not as scary as it seems
>
>
> Header libraries do almost everything in such a context.
>
> (and using a constexpr variable for its address rather than its value is a
> little unusual in any case).
>
>
> But it happens unintentionally when passing to a parameter of const & or
> class type.
>
>  My impression had been that variable templates were just syntactic sugar
>> for a class with a single static data member. Reviewing now, static data
>> members of class templates have an exception to the ODR rule but variable
>> templates do not. (Putting a variable template in a header at all currently
>> appears to be illegal!)
>>
>
> I agree that [basic.def.odr]p6 should apply to variable templates (and
> currently does not). I think the consequence of this is that the same
> variable template can have different definitions in different TUs, not that
> it can't be defined in multiple TUs, but either way, that's the wrong rule.
> I've forwarded this to Mike as a core issue.
>
>
> I prefer to think in terms of linkage -- whether it's the same object in
> every TU.
>
> Constexpr objects should have a definition in each TU, regardless of
> templating or linkage. Non-trivially constructible objects must be defined
> in only one TU to have a well-defined static initialization order, a
> requirement following from linkage which is unaffected by templating.
>
> So I'm leaning toward thinking now that templates are a red herring, and
> the entire problem is extern constexpr.
>
>
> Reading N3651 now, I'm very surprised. It only talks about constexpr
>> objects, and its motivation section only discusses constants. But the
>> feature is far more sweeping. For non-constants, it's completely broken if
>> specializations in different TUs don't name the same object.
>
>
> The wording for a significant feature isn't likely to be perfect the first
> time around =)
>
>
> What kind of quality is C++14 aiming for? Will it pass the ballot because
> consensus of intent is clear in the minds of those voting?
>
> I feel vehemently that the normative text of the standard is the only
> authority that people can really access, but on the other hand we do have
> to get it out the door, and the sooner that happens the sooner the next
> standard (hopefully C++17) will be available as well. Being February now,
> it seems the risk of slipping to C++15 is already non-negligible.
>
>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e011847d0ec3fbd04f1ad74db
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Feb 4, 2014 at 4:55 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:potswa=
@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> wrote:<br><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><br><div><div class=3D"im"><div>On Feb =
5, 2014, at 3:23 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafoo.co=
..uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt; wrote:</div><br><block=
quote type=3D"cite">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>The problem that pi&lt;T&gt; has internal linkage is easily avoided:</div>=
<div><br></div><div>&nbsp; template&lt;typename T&gt;</div><div>&nbsp; exte=
rn constexpr T pi =3D T(3.1415926535897932385);</div>
</div></div></div></blockquote><div><br></div></div><div><font face=3D"Cour=
ier">extern constexpr</font> itself is broken. You cannot define an extern =
object in two TUs but must define a constexpr object in every TU. I&rsquo;v=
e mentioned it here before and intend to submit a proposal about this.</div=
>
</div></div></blockquote><div><br></div><div>extern constexpr isn&#39;t bro=
ken for variable templates, because notionally template instantiations are =
performed once per program, not once per translation unit, so there&#39;s n=
o multiple-definition problem in this case.</div>
<div><br></div><div>For the non-variable-template case, &#39;inline extern =
constexpr&#39; semantics would probably be useful (that is, allow multiple =
definitions of an extern constexpr variable, but require them to be equival=
ent under the ODR, just as we do for inline functions). I think that&#39;s =
what you&#39;re suggesting?</div>
<div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:bre=
ak-word"><div><div>Hmm, come to think of it, function templates of static l=
inkage are supported, so it would seem to be wrong to force variable templa=
tes to have extern linkage. Const-qualified and constexpr objects get stati=
c linkage by default so the extern will be needed even after fixing the ODR=
, unless we make default linkage even less consistent.</div>
<div class=3D"im"><br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote">
<div>Also, the problem would only have arisen if we used the address of pi&=
lt;T&gt; in an inline function or a template, so it&#39;s not as scary as i=
t seems </div></div></div></div></blockquote><div><br></div></div><div>
Header libraries do almost everything in such a context.</div><div class=3D=
"im"><br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_ext=
ra"><div class=3D"gmail_quote"><div>(and using a constexpr variable for its=
 address rather than its value is a little unusual in any case).</div>
</div></div></div></blockquote><div><br></div></div><div>But it happens uni=
ntentionally when passing to a parameter of <font face=3D"Courier">const &a=
mp;</font> or class type.</div><div class=3D"im"><br><blockquote type=3D"ci=
te">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">
My impression had been that variable templates were just syntactic sugar fo=
r a class with a single static data member. Reviewing now, static data memb=
ers of class templates have an exception to the ODR rule but variable templ=
ates do not. (Putting a variable template in a header at all currently appe=
ars to be illegal!)<br>

</blockquote><div><br></div><div>I agree that [basic.def.odr]p6 should appl=
y to variable templates (and currently does not). I think the consequence o=
f this is that the same variable template can have different definitions in=
 different TUs, not that it can&#39;t be defined in multiple TUs, but eithe=
r way, that&#39;s the wrong rule. I&#39;ve forwarded this to Mike as a core=
 issue.</div>
</div></div></div></blockquote><div><br></div></div><div>I prefer to think =
in terms of linkage &mdash; whether it&rsquo;s the same object in every TU.=
</div><div><br></div><div>Constexpr objects should have a definition in eac=
h TU, regardless of templating or linkage. Non-trivially constructible obje=
cts must be defined in only one TU to have a well-defined static initializa=
tion order, a requirement following from linkage which is unaffected by tem=
plating.</div>
<div><br></div><div>So I&rsquo;m leaning toward thinking now that templates=
 are a red herring, and the entire problem is <font face=3D"Courier">extern=
 constexpr</font>.</div><div class=3D"im"><br><blockquote type=3D"cite"><di=
v dir=3D"ltr">
<div class=3D"gmail_extra"><div class=3D"gmail_quote">
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex">
Reading N3651 now, I&#39;m very surprised. It only talks about constexpr ob=
jects, and its motivation section only discusses constants. But the feature=
 is far more sweeping. For non-constants, it&#39;s completely broken if spe=
cializations in different TUs don&#39;t name the same object.</blockquote>

<div><br></div><div>The wording for a significant feature isn&#39;t likely =
to be perfect the first time around =3D)</div></div></div></div></blockquot=
e><div><br></div></div><div>What kind of quality is C++14 aiming for? Will =
it pass the ballot because consensus of intent is clear in the minds of tho=
se voting?</div>
<div><br></div><div>I feel vehemently that the normative text of the standa=
rd is the only authority that people can really access, but on the other ha=
nd we do have to get it out the door, and the sooner that happens the soone=
r the next standard (hopefully C++17) will be available as well. Being Febr=
uary now, it seems the risk of slipping to C++15 is already non-negligible.=
</div>
<div><br></div></div></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e011847d0ec3fbd04f1ad74db--

.


Author: potswa@gmail.com
Date: Thu, 6 Feb 2014 13:08:03 +0800
Raw View
--Apple-Mail=_8504DD6F-03BE-4334-A87C-BBA9D6608F3A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 5, 2014, at 1:38 PM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> potswa@gmail.com writes:
>=20
> | Vague linkage is identical to that of inline functions, no?
>=20
> it isn't defined in the standards text.

I'll assume "yes." (GNU should have a formal definition.)

> | I agree that constexpr objects should be as such. Unfortunately the
> | concept doesn't extend to dynamic initialization.
>=20
> I view linkage and dynamic initialization as orthogonal issues;  why do
> you think they intersect here?

I was thinking that a dynamic initialization/destruction must be performed =
in sequence with those resulting from other definitions in the same TU. But=
 upon looking it up, unordered dynamic initialization should apply to varia=
ble templates, by analogy with the static data members they sugar-coat. Thi=
s is essentially like vague linkage for objects.

Note that according to this rule, it's unsafe to access a dynamically initi=
alized variable template (or class template static data member) before the =
first statement of main.

> | The ODR doesn't and cannot apply to objects of
> | internal linkage because they are separate -- that is the purpose of
> | internal linkage.
>=20
> From a low-level point of view, that is probably correct.  But it
> misses the entire point and idea behind ODR. =20

Internal linkage only provides an escape from the ODR by allowing different=
 entities in different TUs to have the same name. Name allocation should be=
 at the user's discretion.

> The internal
> linkage stuff is largely orthogonal and (from what I know) a historical
> accident which needed to be taken into account because constants tend to
> be prominently present in header files.

Internal linkage applies when a declaration is "private" to a TU.

Sacrificing the orthogonality of linkage and ODR would make things pretty c=
onfusing, not least to the user.

> Consequently, when looking at
> ODR, one should keep that perspective; not just the low-level
> (imperfect) implementation we current have in the standards text.=20

It might be nice to grant vague linkage to all names representing core cons=
tant expressions, but it might be too subtle of a breaking change. Specifyi=
ng unordered dynamic initialization for non-templates would be pretty radic=
al and could break e.g. Schwarz counters.

I mentioned non-trivial construction specifically before, but even integer =
objects may require dynamic initialization. The simplest spec remains to de=
fault constants to internal linkage, ignoring the history.

Dynamic initialization is disallowed for constexpr objects though, which is=
 why they are a good candidate for extern (i.e. vague) default linkage.


On Feb 6, 2014, at 3:06 AM, Richard Smith <richard@metafoo.co.uk> wrote:

> On Tue, Feb 4, 2014 at 4:55 PM, <potswa@gmail.com> wrote:
>=20
> extern constexpr itself is broken. You cannot define an extern object in =
two TUs but must define a constexpr object in every TU. I've mentioned it h=
ere before and intend to submit a proposal about this.
>=20
> extern constexpr isn't broken for variable templates, because notionally =
template instantiations are performed once per program, not once per transl=
ation unit, so there's no multiple-definition problem in this case.

Well, the only brokenness in the template case is that the ODR is missing a=
n allowance. For extern, non-constexpr ones, [basic.start.init] also forget=
s to mention when they get initialized. These are normative, not "real-worl=
d" issues.

> For the non-variable-template case, 'inline extern constexpr' semantics w=
ould probably be useful (that is, allow multiple definitions of an extern c=
onstexpr variable, but require them to be equivalent under the ODR, just as=
 we do for inline functions). I think that's what you're suggesting?

Yes -- but since this essentially requires non-templates to behave the same=
 as templates, the specification might as well not mention templating.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_8504DD6F-03BE-4334-A87C-BBA9D6608F3A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 5=
, 2014, at 1:38 PM, Gabriel Dos Reis &lt;<a href=3D"mailto:gdr@axiomatics.o=
rg">gdr@axiomatics.org</a>&gt; wrote:</div><br class=3D"Apple-interchange-n=
ewline"><blockquote type=3D"cite"><a href=3D"mailto:potswa@gmail.com">potsw=
a@gmail.com</a> writes:<br><br>| Vague linkage is identical to that of inli=
ne functions, no?<br><br>it isn't defined in the standards text.<br></block=
quote><div><br></div><div>I&rsquo;ll assume &ldquo;yes.&rdquo; (GNU should =
have a formal definition.)</div><br><blockquote type=3D"cite">| I agree tha=
t constexpr objects should be as such. Unfortunately the<br>| concept doesn=
&rsquo;t extend to dynamic initialization.<br><br>I view linkage and dynami=
c initialization as orthogonal issues; &nbsp;why do<br>you think they inter=
sect here?<br></blockquote><div><br></div><div>I was thinking that a dynami=
c initialization/destruction must be performed in sequence with those resul=
ting from other definitions in the same TU. But upon looking it up,&nbsp;<i=
>unordered dynamic initialization</i>&nbsp;should apply to variable templat=
es, by analogy with the static data members they sugar-coat. This is essent=
ially like vague linkage for objects.</div><div><br></div><div>Note that ac=
cording to this rule, it&rsquo;s unsafe to access a dynamically initialized=
 variable template (or class template static data member) before the first =
statement of <font face=3D"Courier">main</font>.</div><div><br></div><block=
quote type=3D"cite">| The ODR doesn&rsquo;t and cannot apply to objects of<=
br>| internal linkage because they are separate &mdash; that is the purpose=
 of<br>| internal linkage.<br><br></blockquote><blockquote type=3D"cite">Fr=
om a low-level point of view, that is probably correct. &nbsp;But it<br>mis=
ses the entire point and idea behind ODR. &nbsp;</blockquote><div><br></div=
><div>Internal linkage only provides an escape from the ODR by allowing dif=
ferent entities in different TUs to have the same name. Name allocation sho=
uld be at the user&rsquo;s discretion.</div><br><blockquote type=3D"cite">T=
he internal<br>linkage stuff is largely orthogonal and (from what I know) a=
 historical<br>accident which needed to be taken into account because const=
ants tend to<br>be prominently present in header files.</blockquote><div><b=
r></div><div>Internal linkage applies when a declaration is "private" to a =
TU.</div><div><br></div><div>Sacrificing the orthogonality of linkage and O=
DR would make things pretty confusing, not least to the user.</div><br><blo=
ckquote type=3D"cite">Consequently, when looking at<br>ODR, one should keep=
 that perspective; not just the low-level<br>(imperfect) implementation we =
current have in the standards text. <br></blockquote><div><br></div><div>It=
 might be nice to grant vague linkage to all names representing core consta=
nt expressions, but it might be too subtle of a breaking change. Specifying=
 unordered dynamic initialization for non-templates would be pretty radical=
 and could break e.g. Schwarz counters.</div><div><br></div><div>I mentione=
d non-trivial construction specifically before, but even integer objects ma=
y require dynamic initialization. The simplest spec remains to default cons=
tants to internal linkage, ignoring the history.</div><div><br></div><div>D=
ynamic initialization is disallowed for constexpr objects though, which is =
why they are a good candidate for extern (i.e. vague) default linkage.</div=
><div><br></div><div><br></div><div><div>On Feb 6, 2014, at 3:06 AM, Richar=
d Smith &lt;<a href=3D"mailto:richard@metafoo.co.uk">richard@metafoo.co.uk<=
/a>&gt; wrote:</div><br class=3D"Apple-interchange-newline"><blockquote typ=
e=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_=
quote">On Tue, Feb 4, 2014 at 4:55 PM,&nbsp;<span dir=3D"ltr">&lt;<a href=
=3D"mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</sp=
an>&nbsp;wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0=
px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204)=
; border-left-style: solid; padding-left: 1ex; position: static; z-index: a=
uto;"><div style=3D"word-wrap: break-word;"><br><div><div class=3D"im"><fon=
t face=3D"Courier">extern constexpr</font>&nbsp;itself is broken. You canno=
t define an extern object in two TUs but must define a constexpr object in =
every TU. I&rsquo;ve mentioned it here before and intend to submit a propos=
al about this.</div></div></div></blockquote><div><br></div><div>extern con=
stexpr isn't broken for variable templates, because notionally template ins=
tantiations are performed once per program, not once per translation unit, =
so there's no multiple-definition problem in this case.</div></div></div></=
div></blockquote><div><br></div><div>Well, the only brokenness in the templ=
ate case is that the ODR is missing an allowance. For extern, non-constexpr=
 ones, [basic.start.init] also forgets to mention when they get initialized=
.. These are normative, not "real-world" issues.</div><div><br></div><blockq=
uote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote">For the non-variable-template case, 'inline extern constex=
pr' semantics would probably be useful (that is, allow multiple definitions=
 of an extern constexpr variable, but require them to be equivalent under t=
he ODR, just as we do for inline functions). I think that's what you're sug=
gesting?</div></div></div></blockquote><div><br></div><div>Yes &mdash; but =
since this essentially requires non-templates to behave the same as templat=
es, the specification might as well not mention templating.</div><div><br><=
/div></div></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_8504DD6F-03BE-4334-A87C-BBA9D6608F3A--

.


Author: Tom Honermann <thonermann@coverity.com>
Date: Thu, 6 Feb 2014 11:41:51 -0500
Raw View
On 02/06/2014 12:08 AM, potswa@gmail.com wrote:
> Note that according to this rule, it's unsafe to access a dynamically
> initialized variable template (or class template static data member)
> before the first statement of main.

That appears to be the case for gcc (4.6.3) and clang (3.4) with some
implementation divergence.  gcc appears to sequence dynamic
initialization of instantiations of class template static data members
with the global scope declaration containing the first reference to the
instantiation.  In the test case below, moving the S2 constructor
out-of-line and placing it after the '!DEFINE_EARLY' definition avoids
the noted seg fault.  Clang appears to sequence such dynamic
initializations after all other global dynamic inits.

$ cat t.cpp
template<typename T>
T get() { return T(); }

template<typename T>
struct ST {
     static T t;
};

struct S {
     S() : b(true) {}
     bool b;
};

// Test case does not seg fault when compiled by gcc and DEFINE_EARLY!=0
// Test case *does* seg fault when compiled by clang and DEFINE_EARLY!=0
#if DEFINE_EARLY
template<typename T>
T ST<T>::t = get<T>();
#endif

struct S2 {
     S2() {
         if (ST<S>::t.b) {
           // OK
         } else {
           // Not OK!
           *((volatile int*)0) = 0;
         }
     }
};

// Test case *does* seg fault when compiled by gcc and DEFINE_EARLY==0
// Test case *does* seg fault when compiled by clang and DEFINE_EARLY==0
#if !DEFINE_EARLY
template<typename T>
T ST<T>::t = get<T>();
#endif

S2 s2;

int main() {
}

$ g++ t.cpp -o t
$ ./t
Segmentation fault (core dumped)

$ g++ -DDEFINE_EARLY t.cpp -o t
$ ./t

$ clang++ t.cpp -o t
$ ./t
Segmentation fault (core dumped)

$ clang++ -DDEFINE_EARLY t.cpp -o t
$ ./t
Segmentation fault (core dumped)

Tom.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 6 Feb 2014 10:43:29 -0800
Raw View
--089e011613d2e47db204f1c13f96
Content-Type: text/plain; charset=ISO-8859-1

On Wed, Feb 5, 2014 at 9:08 PM, <potswa@gmail.com> wrote:

> On Feb 6, 2014, at 3:06 AM, Richard Smith <richard@metafoo.co.uk> wrote:
>
> On Tue, Feb 4, 2014 at 4:55 PM, <potswa@gmail.com> wrote:
>
>>
>> extern constexpr itself is broken. You cannot define an extern object in
>> two TUs but must define a constexpr object in every TU. I've mentioned it
>> here before and intend to submit a proposal about this.
>>
>
> extern constexpr isn't broken for variable templates, because notionally
> template instantiations are performed once per program, not once per
> translation unit, so there's no multiple-definition problem in this case.
>
>
> Well, the only brokenness in the template case is that the ODR is missing
> an allowance. For extern, non-constexpr ones, [basic.start.init] also
> forgets to mention when they get initialized. These are normative, not
> "real-world" issues.
>

Yes; FYI, the latter issue is core issue 1744:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1744.

For the non-variable-template case, 'inline extern constexpr' semantics
> would probably be useful (that is, allow multiple definitions of an extern
> constexpr variable, but require them to be equivalent under the ODR, just
> as we do for inline functions). I think that's what you're suggesting?
>
>
> Yes -- but since this essentially requires non-templates to behave the same
> as templates, the specification might as well not mention templating.
>

I don't think it would need to mention templates, just like we don't talk
about templates when we say how inline functions behave. However, the rule
still wouldn't apply to the case of a variable template specialization,
because there is (notionally) only ever one definition of a particular
variable template specialization anyway (within some instantiation unit).

I think there's also a syntactic question -- we could specify that 'extern
constexpr' has this behavior (which would be somewhat non-uniform and would
give people no way to avoid weak linkage in some cases), or we could allow
'inline' to be specified on a variable definition for this.  The latter is
arguaby more general, more useful and more orthogonal, so that's the
direction I think I'd prefer to see.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e011613d2e47db204f1c13f96
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Feb 5, 2014 at 9:08 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:potswa=
@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> wrote:<br><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padd=
ing-left:1ex">
<div style=3D"word-wrap:break-word"><div><div><div class=3D"im"><div>On Feb=
 6, 2014, at 3:06 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafoo.c=
o.uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt; wrote:</div><br></div=
><blockquote type=3D"cite">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
 class=3D"im">On Tue, Feb 4, 2014 at 4:55 PM,&nbsp;<span dir=3D"ltr">&lt;<a=
 href=3D"mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt=
;</span>&nbsp;wrote:<br>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:s=
olid;padding-left:1ex"><div style=3D"word-wrap:break-word"><br><div class=
=3D"im">
<div><div><font face=3D"Courier">extern constexpr</font>&nbsp;itself is bro=
ken. You cannot define an extern object in two TUs but must define a conste=
xpr object in every TU. I&rsquo;ve mentioned it here before and intend to s=
ubmit a proposal about this.</div>
</div></div></div></blockquote><div class=3D"im"><div><br></div><div>extern=
 constexpr isn&#39;t broken for variable templates, because notionally temp=
late instantiations are performed once per program, not once per translatio=
n unit, so there&#39;s no multiple-definition problem in this case.</div>
</div></div></div></div></blockquote><div><br></div><div>Well, the only bro=
kenness in the template case is that the ODR is missing an allowance. For e=
xtern, non-constexpr ones, [basic.start.init] also forgets to mention when =
they get initialized. These are normative, not &quot;real-world&quot; issue=
s.</div>
</div></div></div></blockquote><div><br></div><div>Yes; FYI, the latter iss=
ue is core issue 1744:&nbsp;<a href=3D"http://www.open-std.org/jtc1/sc22/wg=
21/docs/cwg_active.html#1744">http://www.open-std.org/jtc1/sc22/wg21/docs/c=
wg_active.html#1744</a>.</div>
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><d=
iv>
<div class=3D"im"><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"=
gmail_extra"><div class=3D"gmail_quote">For the non-variable-template case,=
 &#39;inline extern constexpr&#39; semantics would probably be useful (that=
 is, allow multiple definitions of an extern constexpr variable, but requir=
e them to be equivalent under the ODR, just as we do for inline functions).=
 I think that&#39;s what you&#39;re suggesting?</div>
</div></div></blockquote><div><br></div></div><div>Yes &mdash; but since th=
is essentially requires non-templates to behave the same as templates, the =
specification might as well not mention templating.</div></div></div></div>=
</blockquote>
<div><br></div><div>I don&#39;t think it would need to mention templates, j=
ust like we don&#39;t talk about templates when we say how inline functions=
 behave. However, the rule still wouldn&#39;t apply to the case of a variab=
le template specialization, because there is (notionally) only ever one def=
inition of a particular variable template specialization anyway (within som=
e instantiation unit).</div>
<div><br></div><div>I think there&#39;s also a syntactic question -- we cou=
ld specify that &#39;extern constexpr&#39; has this behavior (which would b=
e somewhat non-uniform and would give people no way to avoid weak linkage i=
n some cases), or we could allow &#39;inline&#39; to be specified on a vari=
able definition for this. &nbsp;The latter is arguaby more general, more us=
eful and more orthogonal, so that&#39;s the direction I think I&#39;d prefe=
r to see.</div>
</div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e011613d2e47db204f1c13f96--

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 7 Feb 2014 07:25:17 +0800
Raw View
--Apple-Mail=_2E8E6953-8127-4B85-9502-FCAE8E2C4A84
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 7, 2014, at 2:43 AM, Richard Smith <richard@metafoo.co.uk> wrote:

> I don't think it would need to mention templates, just like we don't talk=
 about templates when we say how inline functions behave. However, the rule=
 still wouldn't apply to the case of a variable template specialization, be=
cause there is (notionally) only ever one definition of a particular variab=
le template specialization anyway (within some instantiation unit).

Changing the default linkage of constexpr to extern would apply to template=
s, and would be a breaking change.

> I think there's also a syntactic question -- we could specify that 'exter=
n constexpr' has this behavior (which would be somewhat non-uniform and wou=
ld give people no way to avoid weak linkage in some cases), or we could all=
ow 'inline' to be specified on a variable definition for this.  The latter =
is arguaby more general, more useful and more orthogonal, so that's the dir=
ection I think I'd prefer to see.

Because the semantics currently defined for extern constexpr are broken to =
the point of uselessness, modification is safe enough. (Not a breaking chan=
ge.) Using orthogonality to preserve a defect is a bad thing IMHO. I think =
the inline keyword could be put to better use, namely to re-evaluate an exp=
ression inline where a name is used. Most people still associate the keywor=
d with function inlining, not vague linkage.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_2E8E6953-8127-4B85-9502-FCAE8E2C4A84
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Diso-8859-1"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mo=
de: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 7, =
2014, at 2:43 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafoo.co.uk=
">richard@metafoo.co.uk</a>&gt; wrote:</div><br class=3D"Apple-interchange-=
newline"><blockquote type=3D"cite"><div style=3D"font-family: Helvetica; fo=
nt-size: 12px; font-style: normal; font-variant: normal; font-weight: norma=
l; letter-spacing: normal; line-height: normal; orphans: auto; text-align: =
start; text-indent: 0px; text-transform: none; white-space: normal; widows:=
 auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir=3D"ltr"=
><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>I don't think i=
t would need to mention templates, just like we don't talk about templates =
when we say how inline functions behave. However, the rule still wouldn't a=
pply to the case of a variable template specialization, because there is (n=
otionally) only ever one definition of a particular variable template speci=
alization anyway (within some instantiation unit).</div></div></div></div><=
/div></blockquote><div><br></div><div>Changing the default linkage of const=
expr to extern would apply to templates, and would be a breaking change.</d=
iv><br><blockquote type=3D"cite"><div style=3D"font-family: Helvetica; font=
-size: 12px; font-style: normal; font-variant: normal; font-weight: normal;=
 letter-spacing: normal; line-height: normal; orphans: auto; text-align: st=
art; text-indent: 0px; text-transform: none; white-space: normal; widows: a=
uto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir=3D"ltr"><=
div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>I think there's a=
lso a syntactic question -- we could specify that 'extern constexpr' has th=
is behavior (which would be somewhat non-uniform and would give people no w=
ay to avoid weak linkage in some cases), or we could allow 'inline' to be s=
pecified on a variable definition for this. &nbsp;The latter is arguaby mor=
e general, more useful and more orthogonal, so that's the direction I think=
 I'd prefer to see.</div></div></div></div></div></blockquote><div><br></di=
v><div>Because the semantics currently defined for extern constexpr are bro=
ken to the point of uselessness, modification is safe enough. (Not a breaki=
ng change.) Using orthogonality to preserve a defect is a bad thing IMHO. I=
 think the inline keyword could be put to better use, namely to re-evaluate=
 an expression inline where a name is used. Most people still associate the=
 keyword with function inlining, not vague linkage.</div><div><br></div></d=
iv></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_2E8E6953-8127-4B85-9502-FCAE8E2C4A84--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 6 Feb 2014 16:03:59 -0800
Raw View
--047d7b66f2f71569f004f1c5ba28
Content-Type: text/plain; charset=ISO-8859-1

On Thu, Feb 6, 2014 at 3:25 PM, David Krauss <potswa@gmail.com> wrote:

>
> On Feb 7, 2014, at 2:43 AM, Richard Smith <richard@metafoo.co.uk> wrote:
>
> I don't think it would need to mention templates, just like we don't talk
> about templates when we say how inline functions behave. However, the rule
> still wouldn't apply to the case of a variable template specialization,
> because there is (notionally) only ever one definition of a particular
> variable template specialization anyway (within some instantiation unit).
>
>
> Changing the default linkage of constexpr to extern would apply to
> templates, and would be a breaking change.
>

I didn't (mean to) suggest changing the linkage of constexpr variables.


> I think there's also a syntactic question -- we could specify that 'extern
> constexpr' has this behavior (which would be somewhat non-uniform and would
> give people no way to avoid weak linkage in some cases), or we could allow
> 'inline' to be specified on a variable definition for this.  The latter is
> arguaby more general, more useful and more orthogonal, so that's the
> direction I think I'd prefer to see.
>
>
> Because the semantics currently defined for extern constexpr are broken to
> the point of uselessness, modification is safe enough.
>

The current rules are not broken, but don't necessarily do what some people
would like. I think it's entirely reasonable for me to write:

my.h:

extern const MyType foo;

my.cc:

#include "my.h"
extern constexpr MyType foo = "blah"; // constexpr to guarantee static
initialization

.... and I see no reason to introduce weak linkage into this code.

(Not a breaking change.) Using orthogonality to preserve a defect is a bad
> thing IMHO.
>

C++'s tendency towards non-orthogonal syntax for orthogonal ideas has been
the source of a significant amount of confusion and complexity. For
instance: what's the linkage of a namespace-scope variable? Well, it's the
same as the namespace. Except if it's declared 'static' or 'const', when
it's internal. Except if it's declared 'extern', when you don't look at
'const'. Oh, but wait, 'thread_local' implies 'static', so that means
internal linkage too. Except that 'thread_local extern' does not imply
'static'. Oh, and what about 'constexpr' references? They're 'constexpr'
but never 'const', do they get internal linkage or external?


> I think the inline keyword could be put to better use, namely to
> re-evaluate an expression inline where a name is used.
>

I don't think it's reasonable to think of keywords as a scarce resource and
try to find the best use for each one in each context.

Most people still associate the keyword with function inlining, not vague
> linkage.
>

You can apply the function inlining notion here too (the 'inline' allows
the external-linkage constexpr variable's value to be inlined across TUs).

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--047d7b66f2f71569f004f1c5ba28
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Feb 6, 2014 at 3:25 PM, David Krauss <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex"><div style=3D"word-wrap:break-word"><br><div><div class=3D=
"im">
<div>On Feb 7, 2014, at 2:43 AM, Richard Smith &lt;<a href=3D"mailto:richar=
d@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt; wrote:</di=
v><br><blockquote type=3D"cite"><div style=3D"font-family:Helvetica;font-si=
ze:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spa=
cing:normal;line-height:normal;text-align:start;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>I don&#39;t think it would need to mention templates, just like we don&#39=
;t talk about templates when we say how inline functions behave. However, t=
he rule still wouldn&#39;t apply to the case of a variable template special=
ization, because there is (notionally) only ever one definition of a partic=
ular variable template specialization anyway (within some instantiation uni=
t).</div>
</div></div></div></div></blockquote><div><br></div></div><div>Changing the=
 default linkage of constexpr to extern would apply to templates, and would=
 be a breaking change.</div></div></div></blockquote><div><br></div><div>
I didn&#39;t (mean to) suggest changing the linkage of constexpr variables.=
</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);borde=
r-left-style:solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div><div class=3D"im"><blockquote type=
=3D"cite"><div style=3D"font-family:Helvetica;font-size:12px;font-style:nor=
mal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-heigh=
t:normal;text-align:start;text-indent:0px;text-transform:none;white-space:n=
ormal;word-spacing:0px">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>I think there&#39;s also a syntactic question -- we could specify that &#3=
9;extern constexpr&#39; has this behavior (which would be somewhat non-unif=
orm and would give people no way to avoid weak linkage in some cases), or w=
e could allow &#39;inline&#39; to be specified on a variable definition for=
 this. =A0The latter is arguaby more general, more useful and more orthogon=
al, so that&#39;s the direction I think I&#39;d prefer to see.</div>
</div></div></div></div></blockquote><div><br></div></div><div>Because the =
semantics currently defined for extern constexpr are broken to the point of=
 uselessness, modification is safe enough. </div></div></div></blockquote>
<div><br></div><div>The current rules are not broken, but don&#39;t necessa=
rily do what some people would like. I think it&#39;s entirely reasonable f=
or me to write:</div><div><br></div><div>my.h:</div><div><br></div><div>
extern const MyType foo;</div><div><br></div><div>my.cc:</div><div><br></di=
v><div>#include &quot;my.h&quot;</div><div>extern constexpr MyType foo =3D =
&quot;blah&quot;; // constexpr to guarantee static initialization</div><div=
>
<br></div><div>... and I see no reason to introduce weak linkage into this =
code.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div><div>(Not a breaking change.) Usin=
g orthogonality to preserve a defect is a bad thing IMHO.</div></div></div>=
</blockquote><div><br></div><div>C++&#39;s tendency towards non-orthogonal =
syntax for orthogonal ideas has been the source of a significant amount of =
confusion and complexity. For instance: what&#39;s the linkage of a namespa=
ce-scope variable? Well, it&#39;s the same as the namespace. Except if it&#=
39;s declared &#39;static&#39; or &#39;const&#39;, when it&#39;s internal. =
Except if it&#39;s declared &#39;extern&#39;, when you don&#39;t look at &#=
39;const&#39;. Oh, but wait, &#39;thread_local&#39; implies &#39;static&#39=
;, so that means internal linkage too. Except that &#39;thread_local extern=
&#39; does not imply &#39;static&#39;. Oh, and what about &#39;constexpr&#3=
9; references? They&#39;re &#39;constexpr&#39; but never &#39;const&#39;, d=
o they get internal linkage or external?</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><di=
v>I think the inline keyword could be put to better use, namely to re-evalu=
ate an expression inline where a name is used.</div>
</div></div></blockquote><div><br></div><div>I don&#39;t think it&#39;s rea=
sonable to think of keywords as a scarce resource and try to find the best =
use for each one in each context.</div><div><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
>
<div style=3D"word-wrap:break-word">Most people still associate the keyword=
 with function inlining, not vague linkage.</div></blockquote><div><br></di=
v><div>You can apply the function inlining notion here too (the &#39;inline=
&#39; allows the external-linkage constexpr variable&#39;s value to be inli=
ned across TUs).</div>
</div></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b66f2f71569f004f1c5ba28--

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 7 Feb 2014 10:21:14 +0800
Raw View
--Apple-Mail=_C8340C2F-71A8-4D79-B06D-0CB3BCB79F29
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 7, 2014, at 8:03 AM, Richard Smith <richard@metafoo.co.uk> wrote:

> I didn't (mean to) suggest changing the linkage of constexpr variables.

Ah. I did. That's what GDR and I were discussing... actually he suggested (=
if I understand) changing all const variables.

>> I think there's also a syntactic question -- we could specify that 'exte=
rn constexpr' has this behavior (which would be somewhat non-uniform and wo=
uld give people no way to avoid weak linkage in some cases), or we could al=
low 'inline' to be specified on a variable definition for this.  The latter=
 is arguaby more general, more useful and more orthogonal, so that's the di=
rection I think I'd prefer to see.
>=20
> Because the semantics currently defined for extern constexpr are broken t=
o the point of uselessness, modification is safe enough.
>=20
> The current rules are not broken, but don't necessarily do what some peop=
le would like. I think it's entirely reasonable for me to write:
>=20
> my.h:
>=20
> extern const MyType foo;
>=20
> my.cc:
>=20
> #include "my.h"
> extern constexpr MyType foo =3D "blah"; // constexpr to guarantee static =
initialization
>=20
> ... and I see no reason to introduce weak linkage into this code.

If to "guarantee static initialization" is the motivation here, note that t=
he spec of static initialization does not mention constexpr. That declarati=
on happens to require that MyType is a literal type, which in turn cannot b=
e dynamically initialized, but that would be better expressed by static_ass=
ert( std::is_literal_type< MyType >::value ). Non-literal types may also re=
ceive static initialization, so the requirement is a bit excessive in eithe=
r case. What's really at issue is requiring that a given initializer be a c=
onstant expression. (I currently have shelved proposal standardese for stat=
ic_assert covering this case.)

Weak object linkage should still permit your example anyway. Having an obje=
ct be constexpr in one TU but not others seems very similar to a function b=
eing inline in one TU but not others, which is explicitly disallowed in =A7=
7.1.2 [dcl.fct.spec]/4. I see no reason to extend that particular restricti=
on to objects. For objects or for functions, there's no problem with access=
 without a definition, as long a the definition(s) that do exist generate a=
 vague linker symbol.

Anyway, I suspect very few people have used constexpr as such, and even few=
er with the impression that it is an intended use-case. It smells like a ha=
ck.

> (Not a breaking change.) Using orthogonality to preserve a defect is a ba=
d thing IMHO.
>=20
> C++'s tendency towards non-orthogonal syntax for orthogonal ideas has bee=
n the source of a significant amount of confusion and complexity. For insta=
nce: what's the linkage of a namespace-scope variable? Well, it's the same =
as the namespace.

Before C++11, I didn't even understand namespaces to have linkage, and I do=
n't recall that transitive rule being there before. I don't think it clarif=
ies or simplifies anything.

> Except if it's declared 'static' or 'const', when it's internal. Except i=
f it's declared 'extern', when you don't look at 'const'. Oh, but wait, 'th=
read_local' implies 'static', so that means internal linkage too. Except th=
at 'thread_local extern' does not imply 'static'. Oh, and what about 'const=
expr' references? They're 'constexpr' but never 'const', do they get intern=
al linkage or external?

And my favorite, "static" class members are extern.

However, all the complication is in determining default linkage, not "non-o=
rthogonal syntax for orthogonal ideas." If you want to express the idea of =
external linkage, the keyword is extern, and if you want to express interna=
l linkage, it's static (except inside class scope, bah). Explicit specifica=
tion should work as the user says, and by-default specification should work=
 to anticipate the user's needs, however complicated that may be. Knowing t=
he complete default linkage rules may help determine the best stylistic usa=
ge of explicit linkage specifiers, but bugs are fixed by tacking on whateve=
r specifier is obviously necessary. (If you never want bugs, then always us=
e a specifier. But who does that, when the defaults work so well?)

True, since C++11 objects declared in an unnamed namespace with the extern =
specifier technically have internal linkage, but behavior of external linka=
ge would still be the same due to inaccessibility of the name.

External linkage is almost invariably what the user wants. The motivation f=
or const implying internal linkage is the likelihood of dynamic initializat=
ion, far as I understand, and even that would perhaps better have not been =
left implicit. Extending that exception to constexpr serves no purpose.

> Most people still associate the keyword with function inlining, not vague=
 linkage.
>=20
> You can apply the function inlining notion here too (the 'inline' allows =
the external-linkage constexpr variable's value to be inlined across TUs).

Do you mean that it would be declared inline in one TU but only defined in =
another? That's the opposite of what inline functions are allowed to do. As=
 a new feature (as opposed to an allowed combination of existing semantics)=
, I don't see the advantage, aside from boosting compiler speed. Compilers =
should optimize that with caching, and no syntactic assistance. (Anyway I s=
uppose modules would eliminate or implement such a cache.)

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_C8340C2F-71A8-4D79-B06D-0CB3BCB79F29
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 7=
, 2014, at 8:03 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafoo.co.=
uk">richard@metafoo.co.uk</a>&gt; wrote:</div><br class=3D"Apple-interchang=
e-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_e=
xtra"><div class=3D"gmail_quote"><div>I didn't (mean to) suggest changing t=
he linkage of constexpr variables.</div></div></div></div></blockquote><div=
><br></div><div>Ah. I did. That&rsquo;s what GDR and I were discussing&hell=
ip; actually he suggested (if I understand) changing all const variables.</=
div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extr=
a"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204=
, 204, 204); border-left-style: solid; padding-left: 1ex; position: static;=
 z-index: auto;">
<div style=3D"word-wrap:break-word"><div class=3D"im"><blockquote type=3D"c=
ite"><div style=3D"font-family:Helvetica;font-size:12px;font-style:normal;f=
ont-variant:normal;font-weight:normal;letter-spacing:normal;line-height:nor=
mal;text-align:start;text-indent:0px;text-transform:none;white-space:normal=
;word-spacing:0px">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>I think there's also a syntactic question -- we could specify that 'extern=
 constexpr' has this behavior (which would be somewhat non-uniform and woul=
d give people no way to avoid weak linkage in some cases), or we could allo=
w 'inline' to be specified on a variable definition for this. &nbsp;The lat=
ter is arguaby more general, more useful and more orthogonal, so that's the=
 direction I think I'd prefer to see.</div>
</div></div></div></div></blockquote><div><br></div></div><div>Because the =
semantics currently defined for extern constexpr are broken to the point of=
 uselessness, modification is safe enough. </div></div></blockquote>
<div><br></div><div>The current rules are not broken, but don't necessarily=
 do what some people would like. I think it's entirely reasonable for me to=
 write:</div><div><br></div><div>my.h:</div><div><br></div><div>
extern const MyType foo;</div><div><br></div><div><a href=3D"http://my.cc">=
my.cc</a>:</div><div><br></div><div>#include "my.h"</div><div>extern conste=
xpr MyType foo =3D "blah"; // constexpr to guarantee static initialization<=
/div><div>
<br></div><div>... and I see no reason to introduce weak linkage into this =
code.</div></div></div></div></blockquote><div><br></div><div>If to "guaran=
tee static initialization&rdquo; is the motivation here, note that the spec=
 of static initialization does not mention constexpr. That declaration happ=
ens to require that MyType is a literal type, which in turn cannot be dynam=
ically initialized, but that would be better expressed by <font face=3D"Cou=
rier">static_assert( std::is_literal_type&lt; MyType &gt;::value )</font>. =
Non-literal types may also receive static initialization, so the requiremen=
t is a bit excessive in either case.&nbsp;What's really at issue is requiri=
ng that a given initializer be a constant expression. (I currently have she=
lved proposal standardese for&nbsp;<font face=3D"Courier">static_assert</fo=
nt>&nbsp;covering this case.)</div><div><br></div><div>Weak object linkage =
should still permit your example anyway. Having an object be constexpr in o=
ne TU but not others seems very similar to a function being inline in one T=
U but not others, which is explicitly disallowed in =A77.1.2 [dcl.fct.spec]=
/4. I see no reason to extend that particular restriction to objects. For o=
bjects or for functions, there&rsquo;s no problem with access without a def=
inition, as long a the definition(s) that do exist generate a vague linker =
symbol.</div><div><br></div><div>Anyway, I suspect very few people have use=
d <font face=3D"Courier">constexpr</font> as such, and even fewer with the =
impression that it is an intended use-case. It smells like a hack.</div><di=
v><br></div><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_=
extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><div style=3D"word-wra=
p:break-word">(Not a breaking change.) Using orthogonality to preserve a de=
fect is a bad thing IMHO.</div></blockquote><div><br></div><div>C++'s tende=
ncy towards non-orthogonal syntax for orthogonal ideas has been the source =
of a significant amount of confusion and complexity. For instance: what's t=
he linkage of a namespace-scope variable? Well, it's the same as the namesp=
ace. </div></div></div></div></blockquote><div><br></div><div>Before C++11,=
 I didn&rsquo;t even understand namespaces to have linkage, and I don&rsquo=
;t recall that transitive rule being there before. I don&rsquo;t think it c=
larifies or simplifies anything.</div><br><blockquote type=3D"cite"><div di=
r=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Except=
 if it's declared 'static' or 'const', when it's internal. Except if it's d=
eclared 'extern', when you don't look at 'const'. Oh, but wait, 'thread_loc=
al' implies 'static', so that means internal linkage too. Except that 'thre=
ad_local extern' does not imply 'static'. Oh, and what about 'constexpr' re=
ferences? They're 'constexpr' but never 'const', do they get internal linka=
ge or external?</div></div></div></div></blockquote><div><br></div><div>And=
 my favorite, &ldquo;static&rdquo; class members are extern.</div><div><br>=
</div><div>However, all the complication is in determining default linkage,=
 not "non-orthogonal syntax for orthogonal ideas.&rdquo; If you want to exp=
ress the idea of external linkage, the keyword is <font face=3D"Courier">ex=
tern</font>, and if you want to express internal linkage, it&rsquo;s <font =
face=3D"Courier">static</font> (except inside class scope, bah). Explicit s=
pecification should work as the user says, and by-default specification sho=
uld work to anticipate the user&rsquo;s needs, however complicated that may=
 be. Knowing the complete default linkage rules may help determine the best=
 stylistic usage of explicit linkage specifiers, but bugs are fixed by tack=
ing on whatever specifier is obviously necessary. (If you never want bugs, =
then always use a specifier. But who does that, when the defaults work so w=
ell?)</div><div><br></div><div>True, since C++11 objects declared in an unn=
amed namespace with the <font face=3D"Courier">extern</font> specifier tech=
nically have internal linkage, but behavior of external linkage would still=
 be the same due to inaccessibility of the name.</div><div><br></div><div>E=
xternal linkage is almost invariably what the user wants. The motivation fo=
r <font face=3D"Courier">const</font> implying internal linkage is the like=
lihood of dynamic initialization, far as I understand, and even that would =
perhaps better have not been left implicit. Extending that exception to <fo=
nt face=3D"Courier">constexpr</font> serves no purpose.</div><div><br></div=
><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div=
 class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex"><div style=3D"word-wrap:break-word"><div>Most people still=
 associate the keyword with function inlining, not vague linkage.</div></di=
v></blockquote><div><div><br></div><div>You can apply the function inlining=
 notion here too (the 'inline' allows the external-linkage constexpr variab=
le's value to be inlined across TUs).</div></div></div></div></div></blockq=
uote><div><br></div><div>Do you mean that it would be declared inline in on=
e TU but only defined in another? That&rsquo;s the opposite of what inline =
functions are allowed to do. As a new feature (as opposed to an allowed com=
bination of existing semantics), I don&rsquo;t see the advantage, aside fro=
m boosting compiler speed. Compilers should optimize that with caching, and=
 no syntactic assistance. (Anyway I suppose modules would eliminate or impl=
ement such a cache.)</div></div><br></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_C8340C2F-71A8-4D79-B06D-0CB3BCB79F29--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 6 Feb 2014 18:53:30 -0800
Raw View
--047d7b8738104c3b3e04f1c818fe
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Thu, Feb 6, 2014 at 6:21 PM, David Krauss <potswa@gmail.com> wrote:

>
> On Feb 7, 2014, at 8:03 AM, Richard Smith <richard@metafoo.co.uk> wrote:
>
> I didn't (mean to) suggest changing the linkage of constexpr variables.
>
>
> Ah. I did. That's what GDR and I were discussing... actually he suggested
> (if I understand) changing all const variables.
>
>  I think there's also a syntactic question -- we could specify that
>> 'extern constexpr' has this behavior (which would be somewhat non-unifor=
m
>> and would give people no way to avoid weak linkage in some cases), or we
>> could allow 'inline' to be specified on a variable definition for this.
>>  The latter is arguaby more general, more useful and more orthogonal, so
>> that's the direction I think I'd prefer to see.
>>
>>
>> Because the semantics currently defined for extern constexpr are broken
>> to the point of uselessness, modification is safe enough.
>>
>
> The current rules are not broken, but don't necessarily do what some
> people would like. I think it's entirely reasonable for me to write:
>
> my.h:
>
> extern const MyType foo;
>
> my.cc:
>
> #include "my.h"
> extern constexpr MyType foo =3D "blah"; // constexpr to guarantee static
> initialization
>
> ... and I see no reason to introduce weak linkage into this code.
>
>
> If to "guarantee static initialization" is the motivation here, note that
> the spec of static initialization does not mention constexpr.
>

I wrote the current wording here =3D)

constexpr requires the initializer to be a constant expression, which is
sufficient (but not necessary) to guarantee that static initialization is
performed. It also requires the destructor to be trivial, which is exactly
the property we need in order to guarantee that no code runs at program
shutdown to destroy the object.


> That declaration happens to require that MyType is a literal type, which
> in turn cannot be dynamically initialized, but that would be better
> expressed by static_assert( std::is_literal_type< MyType >::value ).
>

The literalness of the type is almost irrelevant, and std::is_literal_type
is basically useless. (We came very close to striking the notion from the
standard, even.)


> Weak object linkage should still permit your example anyway. Having an
> object be constexpr in one TU but not others seems very similar to a
> function being inline in one TU but not others, which is explicitly
> disallowed in =A77.1.2 [dcl.fct.spec]/4. I see no reason to extend that
> particular restriction to objects. For objects or for functions, there's =
no
> problem with access without a definition, as long a the definition(s) tha=
t
> do exist generate a vague linker symbol.
>

But weak linkage has a cost, and I don't want to pay that cost. I wouldn't
have to pay if my object were merely 'const' and not 'constexpr'.

Anyway, I suspect very few people have used constexpr as such, and even
> fewer with the impression that it is an intended use-case. It smells like=
 a
> hack.
>
> (Not a breaking change.) Using orthogonality to preserve a defect is a ba=
d
>> thing IMHO.
>>
>
> C++'s tendency towards non-orthogonal syntax for orthogonal ideas has bee=
n
> the source of a significant amount of confusion and complexity. For
> instance: what's the linkage of a namespace-scope variable? Well, it's th=
e
> same as the namespace.
>
>
> Before C++11, I didn't even understand namespaces to have linkage, and I
> don't recall that transitive rule being there before. I don't think it
> clarifies or simplifies anything.
>
> Except if it's declared 'static' or 'const', when it's internal. Except i=
f
> it's declared 'extern', when you don't look at 'const'. Oh, but wait,
> 'thread_local' implies 'static', so that means internal linkage too. Exce=
pt
> that 'thread_local extern' does not imply 'static'. Oh, and what about
> 'constexpr' references? They're 'constexpr' but never 'const', do they ge=
t
> internal linkage or external?
>
>
> And my favorite, "static" class members are extern.
>
> However, all the complication is in determining default linkage, not
> "non-orthogonal syntax for orthogonal ideas." If you want to express the
> idea of external linkage, the keyword is extern, and if you want to
> express internal linkage, it's static (except inside class scope, bah).
>

The complication of determining "default" linkage *is* non-orthogonal
syntax for orthogonal ideas. Type and linkage are orthogonal. But the type
of a variable affects its linkage. Thread-locality is orthogonal to
linkage, but it too affects linkage. Definition versus declaration is
orthogonal to linkage, but "extern" implies "not a definition"... except
when it doesn't. All these quirks make the language harder to learn.

Explicit specification should work as the user says, and by-default
> specification should work to anticipate the user's needs, however
> complicated that may be. Knowing the complete default linkage rules may
> help determine the best stylistic usage of explicit linkage specifiers, b=
ut
> bugs are fixed by tacking on whatever specifier is obviously necessary. (=
If
> you never want bugs, then always use a specifier. But who does that, when
> the defaults work so well?)
>

How many C++ programmers do you think know that 'const' affects linkage?

Most people still associate the keyword with function inlining, not vague
>> linkage.
>>
>
> You can apply the function inlining notion here too (the 'inline' allows
> the external-linkage constexpr variable's value to be inlined across TUs)=
..
>
>
> Do you mean that it would be declared inline in one TU but only defined i=
n
> another? That's the opposite of what inline functions are allowed to do.
>

No, I mean it would have a definition in each TU that uses it, exactly as
is required for inline functions.


> As a new feature (as opposed to an allowed combination of existing
> semantics), I don't see the advantage, aside from boosting compiler speed=
..
> Compilers should optimize that with caching, and no syntactic assistance.
> (Anyway I suppose modules would eliminate or implement such a cache.)
>

The meaning of 'internal linkage' in modules is still being debated. This
is far from clear.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--047d7b8738104c3b3e04f1c818fe
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Feb 6, 2014 at 6:21 PM, David Krauss <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><br><div=
><div class=3D"im"><div>On Feb 7, 2014, at 8:03 AM, Richard Smith &lt;<a hr=
ef=3D"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk=
</a>&gt; wrote:</div>
<br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><=
div class=3D"gmail_quote"><div>I didn&#39;t (mean to) suggest changing the =
linkage of constexpr variables.</div></div></div></div></blockquote><div><b=
r></div>
</div><div>Ah. I did. That&rsquo;s what GDR and I were discussing&hellip; a=
ctually he suggested (if I understand) changing all const variables.</div><=
div class=3D"im"><br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">
<div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite"><div sty=
le=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:n=
ormal;font-weight:normal;letter-spacing:normal;line-height:normal;text-alig=
n:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px">

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>I think there&#39;s also a syntactic question -- we could specify that &#3=
9;extern constexpr&#39; has this behavior (which would be somewhat non-unif=
orm and would give people no way to avoid weak linkage in some cases), or w=
e could allow &#39;inline&#39; to be specified on a variable definition for=
 this. &nbsp;The latter is arguaby more general, more useful and more ortho=
gonal, so that&#39;s the direction I think I&#39;d prefer to see.</div>

</div></div></div></div></blockquote><div><br></div></div><div>Because the =
semantics currently defined for extern constexpr are broken to the point of=
 uselessness, modification is safe enough. </div></div></blockquote>
<div><br></div><div>The current rules are not broken, but don&#39;t necessa=
rily do what some people would like. I think it&#39;s entirely reasonable f=
or me to write:</div><div><br></div><div>my.h:</div><div><br></div><div>

extern const MyType foo;</div><div><br></div><div><a href=3D"http://my.cc" =
target=3D"_blank">my.cc</a>:</div><div><br></div><div>#include &quot;my.h&q=
uot;</div><div>extern constexpr MyType foo =3D &quot;blah&quot;; // constex=
pr to guarantee static initialization</div>
<div>
<br></div><div>... and I see no reason to introduce weak linkage into this =
code.</div></div></div></div></blockquote><div><br></div></div><div>If to &=
quot;guarantee static initialization&rdquo; is the motivation here, note th=
at the spec of static initialization does not mention constexpr.</div>
</div></div></blockquote><div><br></div><div>I wrote the current wording he=
re =3D)</div><div><br></div><div>constexpr requires the initializer to be a=
 constant expression, which is sufficient (but not necessary) to guarantee =
that static initialization is performed. It also requires the destructor to=
 be trivial, which is exactly the property we need in order to guarantee th=
at no code runs at program shutdown to destroy the object.</div>
<div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:bre=
ak-word"><div><div> That declaration happens to require that MyType is a li=
teral type, which in turn cannot be dynamically initialized, but that would=
 be better expressed by <font face=3D"Courier">static_assert( std::is_liter=
al_type&lt; MyType &gt;::value )</font>.</div>
</div></div></blockquote><div><br></div><div>The literalness of the type is=
 almost irrelevant, and std::is_literal_type is basically useless. (We came=
 very close to striking the notion from the standard, even.)</div><div>
&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-wo=
rd"><div><div>Weak object linkage should still permit your example anyway. =
Having an object be constexpr in one TU but not others seems very similar t=
o a function being inline in one TU but not others, which is explicitly dis=
allowed in =A77.1.2 [dcl.fct.spec]/4. I see no reason to extend that partic=
ular restriction to objects. For objects or for functions, there&rsquo;s no=
 problem with access without a definition, as long a the definition(s) that=
 do exist generate a vague linker symbol.</div>
</div></div></blockquote><div><br></div><div>But weak linkage has a cost, a=
nd I don&#39;t want to pay that cost. I wouldn&#39;t have to pay if my obje=
ct were merely &#39;const&#39; and not &#39;constexpr&#39;.</div><div><br>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><d=
iv><div>Anyway, I suspect very few people have used <font face=3D"Courier">=
constexpr</font> as such, and even fewer with the impression that it is an =
intended use-case. It smells like a hack.</div>
<div class=3D"im"><div><br></div><blockquote type=3D"cite"><div dir=3D"ltr"=
><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;borde=
r-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style=3D"word-wrap:break-word">(Not a breaking change.) Using orthogon=
ality to preserve a defect is a bad thing IMHO.</div></blockquote><div><br>=
</div><div>C++&#39;s tendency towards non-orthogonal syntax for orthogonal =
ideas has been the source of a significant amount of confusion and complexi=
ty. For instance: what&#39;s the linkage of a namespace-scope variable? Wel=
l, it&#39;s the same as the namespace. </div>
</div></div></div></blockquote><div><br></div></div><div>Before C++11, I di=
dn&rsquo;t even understand namespaces to have linkage, and I don&rsquo;t re=
call that transitive rule being there before. I don&rsquo;t think it clarif=
ies or simplifies anything.</div>
<div class=3D"im"><br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div>Except if it&#39;s declare=
d &#39;static&#39; or &#39;const&#39;, when it&#39;s internal. Except if it=
&#39;s declared &#39;extern&#39;, when you don&#39;t look at &#39;const&#39=
;. Oh, but wait, &#39;thread_local&#39; implies &#39;static&#39;, so that m=
eans internal linkage too. Except that &#39;thread_local extern&#39; does n=
ot imply &#39;static&#39;. Oh, and what about &#39;constexpr&#39; reference=
s? They&#39;re &#39;constexpr&#39; but never &#39;const&#39;, do they get i=
nternal linkage or external?</div>
</div></div></div></blockquote><div><br></div></div><div>And my favorite, &=
ldquo;static&rdquo; class members are extern.</div><div><br></div><div>Howe=
ver, all the complication is in determining default linkage, not &quot;non-=
orthogonal syntax for orthogonal ideas.&rdquo; If you want to express the i=
dea of external linkage, the keyword is <font face=3D"Courier">extern</font=
>, and if you want to express internal linkage, it&rsquo;s <font face=3D"Co=
urier">static</font> (except inside class scope, bah).</div>
</div></div></blockquote><div><br></div><div>The complication of determinin=
g &quot;default&quot; linkage *is* non-orthogonal syntax for orthogonal ide=
as. Type and linkage are orthogonal. But the type of a variable affects its=
 linkage. Thread-locality is orthogonal to linkage, but it too affects link=
age. Definition versus declaration is orthogonal to linkage, but &quot;exte=
rn&quot; implies &quot;not a definition&quot;... except when it doesn&#39;t=
.. All these quirks make the language harder to learn.</div>
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break=
-word"><div><div>Explicit specification should work as the user says, and b=
y-default specification should work to anticipate the user&rsquo;s needs, h=
owever complicated that may be. Knowing the complete default linkage rules =
may help determine the best stylistic usage of explicit linkage specifiers,=
 but bugs are fixed by tacking on whatever specifier is obviously necessary=
.. (If you never want bugs, then always use a specifier. But who does that, =
when the defaults work so well?)</div>
</div></div></blockquote><div><br></div><div>How many C++ programmers do yo=
u think know that &#39;const&#39; affects linkage?</div><div><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div><div class=3D"im"><blockquote type=
=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_q=
uote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:s=
olid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div>Most people still associate the ke=
yword with function inlining, not vague linkage.</div></div></blockquote><d=
iv><div><br></div><div>You can apply the function inlining notion here too =
(the &#39;inline&#39; allows the external-linkage constexpr variable&#39;s =
value to be inlined across TUs).</div>
</div></div></div></div></blockquote><div><br></div></div><div>Do you mean =
that it would be declared inline in one TU but only defined in another? Tha=
t&rsquo;s the opposite of what inline functions are allowed to do.</div></d=
iv>
</div></blockquote><div><br></div><div>No, I mean it would have a definitio=
n in each TU that uses it, exactly as is required for inline functions.</di=
v><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style=3D"word-wrap:break-word"><div><div>As a new feature (as opposed =
to an allowed combination of existing semantics), I don&rsquo;t see the adv=
antage, aside from boosting compiler speed. Compilers should optimize that =
with caching, and no syntactic assistance. (Anyway I suppose modules would =
eliminate or implement such a cache.)</div>
</div></div></blockquote><div><br></div><div>The meaning of &#39;internal l=
inkage&#39; in modules is still being debated. This is far from clear.&nbsp=
;</div></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b8738104c3b3e04f1c818fe--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 06 Feb 2014 18:58:01 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

| On Feb 7, 2014, at 8:03 AM, Richard Smith <richard@metafoo.co.uk>
| wrote:
|=20
|    =20
|    =20
|    =20
|     I didn't (mean to) suggest changing the linkage of constexpr
|     variables.
|=20
|=20
| Ah. I did. That=E2=80=99s what GDR and I were discussing=E2=80=A6 actuall=
y he
| suggested (if I understand) changing all const variables.

My suggestion, if any, was that the whole notion of linkage is a too
distracting low-level vehicle to implement the ODR.  If we had to
redesign C++ with free hands, linkage will be one of the first things to
be tossed out :-)

[...]

| External linkage is almost invariably what the user wants. The
| motivation for const implying internal linkage is the likelihood of
| dynamic initialization, far as I understand, and even that would
| perhaps better have not been left implicit. Extending that exception
| to constexpr serves no purpose.

No, no, no.  The fact that 'const' implies internal linkage is well
documented in D&E.  Originally, when BS invented 'const' (or 'readonly'
before it got renamed) for C with Classes, it implied extenal linkage.
That was also the semantics retained in the proposal to the C committee.
In the meantime, he conducted more experiments on existing source codes
and came to the conclusion that for the feature to be effective *given
the implementation constraints* at the time, it would be better if the
linkage was internal.  That enabled constant substitution,
e.g. basically the way we know 'const' today.  Consequently, he changed
his spec and implementation.  But C never adopted his changes - which is
one of the reasons why declaring integer variable as const in C does not
allow you to use it in constant expression.

PS: I don't have my copy of D&E handy, so I'm sure someone with correct
the fine details, but the history is essentially that.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 7 Feb 2014 11:09:09 +0800
Raw View
On Feb 7, 2014, at 10:58 AM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> David Krauss <potswa@gmail.com> writes:
>=20
> | External linkage is almost invariably what the user wants. The
> | motivation for const implying internal linkage is the likelihood of
> | dynamic initialization, far as I understand, and even that would
> | perhaps better have not been left implicit. Extending that exception
> | to constexpr serves no purpose.
>=20
> No, no, no.  The fact that 'const' implies internal linkage is well
> documented in D&E.  Originally, when BS invented 'const' (or 'readonly'
> before it got renamed) for C with Classes, it implied extenal linkage.
> That was also the semantics retained in the proposal to the C committee.
> In the meantime, he conducted more experiments on existing source codes
> and came to the conclusion that for the feature to be effective *given
> the implementation constraints* at the time, it would be better if the
> linkage was internal. =20

I should have been clearer that I wasn't considering history, only present =
motivations, which are a somewhat artificial concept. Sorry.

What constraints? Have they changed? Externally linked objects defined in h=
eaders require vague/weak linkage, which I suppose came about with the late=
r invention of implicit and inline functions, and unordered dynamic initial=
ization, which came about much much later.

So only now do we have the tools to do better, and a syntactic case that ac=
tually meets the requirements to be semantically unsurprising, all perfectl=
y according to the original design intent. Carpe diem.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 06 Feb 2014 19:09:50 -0800
Raw View
Richard Smith <richard@metafoo.co.uk> writes:

[...]

|     If to "guarantee static initialization=E2=80=9D is the motivation her=
e,
|     note that the spec of static initialization does not mention
|     constexpr.
|=20
|=20
| I wrote the current wording here =3D)

Well, Jens and I wrote this wording for C++11 and you carried it over
for C++14 :-)=20

| constexpr requires the initializer to be a constant expression, which
| is sufficient (but not necessary) to guarantee that static
| initialization is performed. It also requires the destructor to be
| trivial, which is exactly the property we need in order to guarantee
| that no code runs at program shutdown to destroy the object.

I required the triviality of destructor along with triviality of
copy-constructor from the beginning.  I didn't think (and I still don't
think) that aiming for the necessary-and-sussicient condition here
necessarily gives a better spec and a programming model.

[...]

| But weak linkage has a cost, and I don't want to pay that cost. I
| wouldn't have to pay if my object were merely 'const' and not
| 'constexpr'.

Even for 'constexpr', I don't want to pay for vague linkage.
As I said elsewhere, linkage should disappear from our lexicon :-)

[...]

| How many C++ programmers do you think know that 'const' affects
| linkage?

C++ programmers shouldn't have to talk about linkage.  The fact they
do -- and to a disturbing point in C++03 -- is a defect of
specification.   It is and should remain an implementation artifact --=20
which is even too coarse for modern implementation technologies.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 06 Feb 2014 19:18:00 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

| On Feb 7, 2014, at 10:58 AM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:
|
| > David Krauss <potswa@gmail.com> writes:
| >
| > | External linkage is almost invariably what the user wants. The
| > | motivation for const implying internal linkage is the likelihood of
| > | dynamic initialization, far as I understand, and even that would
| > | perhaps better have not been left implicit. Extending that exception
| > | to constexpr serves no purpose.
| >
| > No, no, no.  The fact that 'const' implies internal linkage is well
| > documented in D&E.  Originally, when BS invented 'const' (or 'readonly'
| > before it got renamed) for C with Classes, it implied extenal linkage.
| > That was also the semantics retained in the proposal to the C committee.
| > In the meantime, he conducted more experiments on existing source codes
| > and came to the conclusion that for the feature to be effective *given
| > the implementation constraints* at the time, it would be better if the
| > linkage was internal.
|
| I should have been clearer that I wasn't considering history, only
| present motivations, which are a somewhat artificial concept. Sorry.
|
| What constraints?

They are documented in D&E.  Remember that C with Class and CFront
depended on the host's C compiler and had to express every C++ concept
in terms of C constructs.  Modifying the host linkers or writing a new
linker of each host was out of question.

D&E is not a just a good reading, but a required reading for anyone
interested in modifying C++, or just musing about why things are the way
they are.

| Have they changed? Externally linked objects defined
| in headers require vague/weak linkage, which I suppose came about with
| the later invention of implicit and inline functions, and unordered
| dynamic initialization, which came about much much later.
|
| So only now do we have the tools to do better, and a syntactic case
| that actually meets the requirements to be semantically unsurprising,
| all perfectly according to the original design intent. Carpe diem.

-- Gaby

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 7 Feb 2014 11:22:50 +0800
Raw View
--Apple-Mail=_C33E5A07-4F33-4861-B5BD-A03FB562ABC0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 7, 2014, at 10:53 AM, Richard Smith <richard@metafoo.co.uk> wrote:

> On Thu, Feb 6, 2014 at 6:21 PM, David Krauss <potswa@gmail.com> wrote:
>=20
> If to "guarantee static initialization" is the motivation here, note that=
 the spec of static initialization does not mention constexpr.
>=20
> I wrote the current wording here =3D)
>=20
> constexpr requires the initializer to be a constant expression, which is =
sufficient (but not necessary) to guarantee that static initialization is p=
erformed. It also requires the destructor to be trivial, which is exactly t=
he property we need in order to guarantee that no code runs at program shut=
down to destroy the object.

But trivial destructibility doesn't appear to be a concern in your example,=
 making it a spurious requirement.

> That declaration happens to require that MyType is a literal type, which =
in turn cannot be dynamically initialized, but that would be better express=
ed by static_assert( std::is_literal_type< MyType >::value ).
>=20
> The literalness of the type is almost irrelevant, and std::is_literal_typ=
e is basically useless. (We came very close to striking the notion from the=
 standard, even.)

I thought literal types were specifically designed to support constexpr sem=
antics? I don't understand what would be struck.

> Weak object linkage should still permit your example anyway. Having an ob=
ject be constexpr in one TU but not others seems very similar to a function=
 being inline in one TU but not others, which is explicitly disallowed in =
=A77.1.2 [dcl.fct.spec]/4. I see no reason to extend that particular restri=
ction to objects. For objects or for functions, there's no problem with acc=
ess without a definition, as long a the definition(s) that do exist generat=
e a vague linker symbol.
>=20
> But weak linkage has a cost, and I don't want to pay that cost. I wouldn'=
t have to pay if my object were merely 'const' and not 'constexpr'.

What cost? I'm not suggesting to make your example behave differently at al=
l. The weak linkage object would be generated by the TU with the definition=
, and would be made visible to non-defining TUs. This isn't exactly like in=
line function linkage, but why not?

> The complication of determining "default" linkage *is* non-orthogonal syn=
tax for orthogonal ideas. Type and linkage are orthogonal. But the type of =
a variable affects its linkage. Thread-locality is orthogonal to linkage, b=
ut it too affects linkage. Definition versus declaration is orthogonal to l=
inkage, but "extern" implies "not a definition"... except when it doesn't. =
All these quirks make the language harder to learn.

Even given all that, removing constexpr from the special case where const i=
mplies internal exacerbates none of these issues. How is the system being b=
roken a rationale for never changing anything about it?

> Explicit specification should work as the user says, and by-default speci=
fication should work to anticipate the user's needs, however complicated th=
at may be. Knowing the complete default linkage rules may help determine th=
e best stylistic usage of explicit linkage specifiers, but bugs are fixed b=
y tacking on whatever specifier is obviously necessary. (If you never want =
bugs, then always use a specifier. But who does that, when the defaults wor=
k so well?)
>=20
> How many C++ programmers do you think know that 'const' affects linkage?

How many even realize there is such a thing as internal linkage? For namesp=
ace members, it was deprecated in C++03 but brought back from the dead.

Awareness is limited by non-diagnosis of ODR violations. And therefore we h=
ave ODR violations due to constexpr right in the standard library, which wa=
s my initial impetus for getting into all this.

As constexpr becomes preferred over const alone, we can nip the problem in =
the bud (in the cases we are currently able) without anyone knowing the dif=
ference.

> No, I mean it would have a definition in each TU that uses it, exactly as=
 is required for inline functions.

How is that different from what constexpr does already? Or are you actually=
 referring to a named-expressions extension?

> As a new feature (as opposed to an allowed combination of existing semant=
ics), I don't see the advantage, aside from boosting compiler speed. Compil=
ers should optimize that with caching, and no syntactic assistance. (Anyway=
 I suppose modules would eliminate or implement such a cache.)
>=20
> The meaning of 'internal linkage' in modules is still being debated. This=
 is far from clear.=20

Now I'm really confused. It sounded like you were proposing a way to refer =
to a constexpr object in one TU from another using inline, which implies ex=
ternal linkage.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_C33E5A07-4F33-4861-B5BD-A03FB562ABC0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 7=
, 2014, at 10:53 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafoo.co=
..uk">richard@metafoo.co.uk</a>&gt; wrote:</div><br class=3D"Apple-interchan=
ge-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_=
extra"><div class=3D"gmail_quote">On Thu, Feb 6, 2014 at 6:21 PM, David Kra=
uss <span dir=3D"ltr">&lt;<a href=3D"mailto:potswa@gmail.com" target=3D"_bl=
ank">potswa@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; borde=
r-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style=
: solid; padding-left: 1ex; position: static; z-index: auto;"><div style=3D=
"word-wrap:break-word"><br><div><div class=3D"im"><div>If to "guarantee sta=
tic initialization&rdquo; is the motivation here, note that the spec of sta=
tic initialization does not mention constexpr.</div></div>
</div></div></blockquote><div><br></div><div>I wrote the current wording he=
re =3D)</div><div><br></div><div>constexpr requires the initializer to be a=
 constant expression, which is sufficient (but not necessary) to guarantee =
that static initialization is performed. It also requires the destructor to=
 be trivial, which is exactly the property we need in order to guarantee th=
at no code runs at program shutdown to destroy the object.</div></div></div=
></div></blockquote><div><br></div><div>But trivial destructibility doesn&r=
squo;t appear to be a concern in your example, making it a spurious require=
ment.</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gma=
il_extra"><div class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div> Th=
at declaration happens to require that MyType is a literal type, which in t=
urn cannot be dynamically initialized, but that would be better expressed b=
y <font face=3D"Courier">static_assert( std::is_literal_type&lt; MyType &gt=
;::value )</font>.</div>
</div></blockquote><div><br></div><div>The literalness of the type is almos=
t irrelevant, and std::is_literal_type is basically useless. (We came very =
close to striking the notion from the standard, even.)</div></div></div></d=
iv></blockquote><div><br></div><div>I thought literal types were specifical=
ly designed to support constexpr semantics? I don&rsquo;t understand what w=
ould be struck.</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div cl=
ass=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-le=
ft-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; =
position: static; z-index: auto;"><div style=3D"word-wrap:break-word"><div>=
Weak object linkage should still permit your example anyway. Having an obje=
ct be constexpr in one TU but not others seems very similar to a function b=
eing inline in one TU but not others, which is explicitly disallowed in =A7=
7.1.2 [dcl.fct.spec]/4. I see no reason to extend that particular restricti=
on to objects. For objects or for functions, there&rsquo;s no problem with =
access without a definition, as long a the definition(s) that do exist gene=
rate a vague linker symbol.</div>
</div></blockquote><div><br></div><div>But weak linkage has a cost, and I d=
on't want to pay that cost. I wouldn't have to pay if my object were merely=
 'const' and not 'constexpr&rsquo;.</div></div></div></div></blockquote><di=
v><br></div><div>What cost? I&rsquo;m not suggesting to make your example b=
ehave differently at all. The weak linkage object would be generated by the=
 TU with the definition, and would be made visible to non-defining TUs. Thi=
s isn&rsquo;t exactly like inline function linkage, but why not?</div><br><=
blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div c=
lass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin: 0px=
 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 20=
4); border-left-style: solid; padding-left: 1ex; position: static; z-index:=
 auto;"><div style=3D"word-wrap:break-word"><div>The complication of determ=
ining "default" linkage *is* non-orthogonal syntax for orthogonal ideas. Ty=
pe and linkage are orthogonal. But the type of a variable affects its linka=
ge. Thread-locality is orthogonal to linkage, but it too affects linkage. D=
efinition versus declaration is orthogonal to linkage, but "extern" implies=
 "not a definition"... except when it doesn't. All these quirks make the la=
nguage harder to learn.</div></div></blockquote></div></div></div></blockqu=
ote><div><br></div><div>Even given all that, removing <font face=3D"Courier=
">constexpr</font> from the special case where const implies internal exace=
rbates none of these issues. How is the system being broken a rationale for=
 never changing anything about it?</div><br><blockquote type=3D"cite"><div =
dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; borde=
r-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style=
: solid; padding-left: 1ex; position: static; z-index: auto;"><div style=3D=
"word-wrap:break-word"><div>Explicit specification should work as the user =
says, and by-default specification should work to anticipate the user&rsquo=
;s needs, however complicated that may be. Knowing the complete default lin=
kage rules may help determine the best stylistic usage of explicit linkage =
specifiers, but bugs are fixed by tacking on whatever specifier is obviousl=
y necessary. (If you never want bugs, then always use a specifier. But who =
does that, when the defaults work so well?)</div>
</div></blockquote><div><br></div><div>How many C++ programmers do you thin=
k know that 'const' affects linkage?</div></div></div></div></blockquote><d=
iv><br></div><div>How many even realize there is such a thing as internal l=
inkage? For namespace members, it was deprecated in C++03 but brought back =
from the dead.</div><div><br></div><div>Awareness is limited by non-diagnos=
is of ODR violations. And therefore we have ODR violations due to constexpr=
 right in the standard library, which was my initial impetus for getting in=
to all this.</div><div><br></div><div>As constexpr becomes preferred over c=
onst alone, we can nip the problem in the bud (in the cases we are currentl=
y able) without anyone knowing the difference.</div><br><blockquote type=3D=
"cite"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quot=
e"><div>No, I mean it would have a definition in each TU that uses it, exac=
tly as is required for inline functions.</div></div></div></div></blockquot=
e><div><br></div><div>How is that different from what constexpr does alread=
y? Or are you actually referring to a named-expressions extension?</div><di=
v><br></div><blockquote type=3D"cite"><div dir=3D"ltr"><div class=3D"gmail_=
extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: r=
gb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: s=
tatic; z-index: auto;">
<div style=3D"word-wrap:break-word"><div>As a new feature (as opposed to an=
 allowed combination of existing semantics), I don&rsquo;t see the advantag=
e, aside from boosting compiler speed. Compilers should optimize that with =
caching, and no syntactic assistance. (Anyway I suppose modules would elimi=
nate or implement such a cache.)</div>
</div></blockquote><div><br></div><div>The meaning of 'internal linkage' in=
 modules is still being debated. This is far from clear.&nbsp;</div></div><=
/div></div></blockquote><div><br></div></div>Now I&rsquo;m really confused.=
 It sounded like you were proposing a way to refer to a constexpr object in=
 one TU from another using inline, which implies external linkage.<div><br>=
</div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_C33E5A07-4F33-4861-B5BD-A03FB562ABC0--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 06 Feb 2014 20:20:08 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

[...]

| I thought literal types were specifically designed to support
| constexpr semantics?

They were -- and I still think it is a good and useful concept.

Between the adoption of constexpr into the draft of standards text, and
the finalization of the standards, constexpr has grown and adopted
several extensions that in the end did not use 'literal type' as
extensively as the original model (conservative now, but viewed as
way too radical at the time) did.

-- Gaby

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 06 Feb 2014 20:23:10 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

[...]

|         Explicit specification should work as the user says, and
|         by-default specification should work to anticipate the user=E2=80=
=99s
|         needs, however complicated that may be. Knowing the complete
|         default linkage rules may help determine the best stylistic
|         usage of explicit linkage specifiers, but bugs are fixed by
|         tacking on whatever specifier is obviously necessary. (If you
|         never want bugs, then always use a specifier. But who does
|         that, when the defaults work so well?)
|=20
|    =20
|    =20
|     How many C++ programmers do you think know that 'const' affects
|     linkage?
|=20
|=20
| How many even realize there is such a thing as internal linkage? For
| namespace members, it was deprecated in C++03 but brought back from
| the dead.
|=20
| Awareness is limited by non-diagnosis of ODR violations. And therefore
| we have ODR violations due to constexpr right in the standard library,
| which was my initial impetus for getting into all this.

I don't understand this statement.

| As constexpr becomes preferred over const alone, we can nip the
| problem in the bud (in the cases we are currently able) without anyone
| knowing the difference.

I am not sure what the problem is that needs fixing.
'constexpr' implies 'const' for the type of the declared variable.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 7 Feb 2014 12:32:53 +0800
Raw View
On Feb 7, 2014, at 12:23 PM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> David Krauss <potswa@gmail.com> writes:
>
> | Awareness is limited by non-diagnosis of ODR violations. And therefore
> | we have ODR violations due to constexpr right in the standard library,
> | which was my initial impetus for getting into all this.
>
> I don't understand this statement.

The ODR is less well and widely understood because compilers seldom diagnose it across TUs.

Tag objects added by C++11 (there are a couple, but I forget the names) are declared (internal) constexpr so any access from an inline function violates the ODR. (The only earlier tag object I can think of is std::nothrow, which is declared extern const.)

> | As constexpr becomes preferred over const alone, we can nip the
> | problem in the bud (in the cases we are currently able) without anyone
> | knowing the difference.
>
> I am not sure what the problem is that needs fixing.
> 'constexpr' implies 'const' for the type of the declared variable.

The problem is that internal linkage is surprising, and results in quiet ODR violation errors.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 06 Feb 2014 20:45:46 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

| On Feb 7, 2014, at 12:23 PM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:
|
| > David Krauss <potswa@gmail.com> writes:
| >
| > | Awareness is limited by non-diagnosis of ODR violations. And therefore
| > | we have ODR violations due to constexpr right in the standard library,
| > | which was my initial impetus for getting into all this.
| >
| > I don't understand this statement.
|
| The ODR is less well and widely understood because compilers seldom
| diagnose it across TUs.

The landscape is changing here, because of the increasing availability
of link-time code-generation/optimizations that work across translation
units.  Furthermore, we are seeing more and more "checking" implementations.

| Tag objects added by C++11 (there are a couple, but I forget the
| names) are declared (internal) constexpr so any access from an inline
| function violates the ODR. (The only earlier tag object I can think of
| is std::nothrow, which is declared extern const.)

Like I said before, this blanked statement is just too strong.
If it isn't wrong, it must be made wrong :-)
The reason is very simple: most of these tag objects have no runtime
semantics; they are only interesting because of their types;
consequently, their addresses shouldn't matter; therefore any talk that
they have been mentioned in inline functions implying ODR violation
should just be made nonsensical.

| > | As constexpr becomes preferred over const alone, we can nip the
| > | problem in the bud (in the cases we are currently able) without anyone
| > | knowing the difference.
| >
| > I am not sure what the problem is that needs fixing.
| > 'constexpr' implies 'const' for the type of the declared variable.
|
| The problem is that internal linkage is surprising, and results in
| quiet ODR violation errors.

From my view, the way to solve this is making the whole notion of
'linkage' less relevant -- not by changing from internal to external.

-- Gaby

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 7 Feb 2014 13:10:59 +0800
Raw View
On Feb 7, 2014, at 12:45 PM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> David Krauss <potswa@gmail.com> writes:
>=20
> The landscape is changing here, because of the increasing availability
> of link-time code-generation/optimizations that work across translation
> units.  Furthermore, we are seeing more and more "checking" implementatio=
ns.

I hope that's true, but can you give examples? The only ones I've heard of =
are historical XLC (with header-caching progressive compilation) and EDG (w=
ith export templates), and only when using non-default options.

Not just examples of LTO, but where the ODR is actually checked with reliab=
ility.

> | Tag objects added by C++11 (there are a couple, but I forget the
> | names) are declared (internal) constexpr so any access from an inline
> | function violates the ODR. (The only earlier tag object I can think of
> | is std::nothrow, which is declared extern const.)
>=20
> Like I said before, this blanked statement is just too strong. =20
> If it isn't wrong, it must be made wrong :-)
> The reason is very simple: most of these tag objects have no runtime
> semantics; they are only interesting because of their types;
> consequently, their addresses shouldn't matter; therefore any talk that
> they have been mentioned in inline functions implying ODR violation
> should just be made nonsensical.

This is true, and another solution to the problem might be to adjust class =
type lvalue-to-rvalue conversion semantics. A tag of enumeration type may b=
e safely passed by value in an inline function because its rvalue conversio=
n satisfies the second bullet in [basic.def.odr]/6. An empty class doesn't =
work the same way because a call to its copy constructor forms a reference =
-- a very minor detail no matter how you slice it.

Internal consistency and compatibility with C could also be improved by suc=
h a tweak as specifying that implicit invocation of a trivial copy construc=
tor ([class.copy] =A712.8/12) need not actually obey function call semantic=
s.

Still, that wouldn't solve the problem of address identity once you do form=
 a reference. Many generic, pass-by-reference functions need to be compatib=
le with constexpr objects. If we want to resolve object identity, the ODR i=
s the place to go. And I don't think using it to merge separate objects wit=
h identical definitions is in keeping with many principles or precedents.

> | The problem is that internal linkage is surprising, and results in
> | quiet ODR violation errors.
>=20
> From my view, the way to solve this is making the whole notion of
> 'linkage' less relevant -- not by changing from internal to external.

How is making it less relevant different from making everything external? (=
Don't tell me because unnamed namespaces have internal linkage ;) .)

And, there are those who purposely use internal linkage to make names local=
 to a TU. Why was this removed from deprecation, by the way?

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Fri, 07 Feb 2014 09:11:35 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

| On Feb 7, 2014, at 12:45 PM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:
|
| > David Krauss <potswa@gmail.com> writes:
| >
| > The landscape is changing here, because of the increasing availability
| > of link-time code-generation/optimizations that work across translation
| > units.  Furthermore, we are seeing more and more "checking" implementations.
|
| I hope that's true, but can you give examples?

Clang and GCC have link-time optimization in released compilers and
production use for a while now.   Microsoft's VC++ has had LTCG for a
while now.

| The only ones I've
| heard of are historical XLC (with header-caching progressive
| compilation) and EDG (with export templates), and only when using
| non-default options.
|
| Not just examples of LTO, but where the ODR is actually checked with
| reliability.

ODR isn't just for the benefit of the user, but alos for internal compiler
data structure consistency.  GCC's implementation of LTO is publically
available and you can peruse the source code.

There might be a degree of check completeness, but that isn't the same
"compilers seldom diagnose it across TUs."

| > | Tag objects added by C++11 (there are a couple, but I forget the
| > | names) are declared (internal) constexpr so any access from an inline
| > | function violates the ODR. (The only earlier tag object I can think of
| > | is std::nothrow, which is declared extern const.)
| >
| > Like I said before, this blanked statement is just too strong.
| > If it isn't wrong, it must be made wrong :-)
| > The reason is very simple: most of these tag objects have no runtime
| > semantics; they are only interesting because of their types;
| > consequently, their addresses shouldn't matter; therefore any talk that
| > they have been mentioned in inline functions implying ODR violation
| > should just be made nonsensical.
|
| This is true, and another solution to the problem might be to adjust
| class type lvalue-to-rvalue conversion semantics. A tag of enumeration
| type may be safely passed by value in an inline function because its
| rvalue conversion satisfies the second bullet in [basic.def.odr]/6. An
| empty class doesn't work the same way because a call to its copy
| constructor forms a reference -- a very minor detail no matter how you
| slice it.

Yes , that is low-level detail of implementation that is incidental, not
fundamental.  Existence of copy-constructor didn't prevent constexpr
function to take arguments by copy even if we were careful with pointers
and addresses.

[...]

| > | The problem is that internal linkage is surprising, and results in
| > | quiet ODR violation errors.
| >
| > From my view, the way to solve this is making the whole notion of
| > 'linkage' less relevant -- not by changing from internal to external.
|
| How is making it less relevant different from making everything
| external? (Don't tell me because unnamed namespaces have internal
| linkage ;) .)

Because 'external' tends to be mapped to something at the implementation
detail level -- e.g. "unique address" which can be a performance hinder
(think of RTTI objects for example.)  Making it less relevant means that
it disappears from our lexicon and we don't have to depend on its
lower-level implications.

| And, there are those who purposely use internal linkage to make names
| local to a TU. Why was this removed from deprecation, by the way?

I don't understand this part of your message.

-- Gaby

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 8 Feb 2014 12:21:19 +0800
Raw View
--Apple-Mail=_FA07E357-2CF9-4604-AD91-A51AE6620062
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 8, 2014, at 1:11 AM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> There might be a degree of check completeness, but that isn't the same
> "compilers seldom diagnose it across TUs."

I don't understand. I don't recall ever seeing an ODR diagnosis result from=
 LTO in particular. So far I've only seen old-fashioned link errors (missin=
g/multiply-defined symbol), which are indeed a species of ODR diagnosis acr=
oss TUs. But slightly mismatched inline functions such as at issue here, an=
d similar issues, still fall through the cracks.

> | An
> | empty class doesn't work the same way because a call to its copy
> | constructor forms a reference -- a very minor detail no matter how you
> | slice it.
>=20
> Yes , that is low-level detail of implementation that is incidental, not
> fundamental.  Existence of copy-constructor didn't prevent constexpr
> function to take arguments by copy even if we were careful with pointers
> and addresses.

ODR-use by initialization of an unused reference is a detail of normative l=
anguage semantics. The low-level implementation likely doesn't care, and no=
 diagnosis is required, so it tends to just work. Certainly we should be ab=
le to change the spec to match the solidly working implementations. The que=
stion is whether it's worthwhile to fix copy constructors in particular, or=
 go after all pass by reference functions (including perfect forwarding).

> Because 'external' tends to be mapped to something at the implementation
> detail level -- e.g. "unique address" which can be a performance hinder
> (think of RTTI objects for example.)  Making it less relevant means that
> it disappears from our lexicon and we don't have to depend on its
> lower-level implications.

Are you suggesting a stepping-stone like ambiguous linkage, such as what st=
ring literals have? Note that this is what makes strings broken as template=
 arguments.

> | And, there are those who purposely use internal linkage to make names
> | local to a TU. Why was this removed from deprecation, by the way?
>=20
> I don't understand this part of your message.

In the C language, internal linkage is the only form of modular encapsulati=
on. Private names are given internal linkage to be hidden from other TUs. S=
ome folks still do this in C++.

C++03 deprecated the static specifier applied to namespace members in favor=
 of unnamed namespaces. C++11 removed the deprecation, and adjusted the lin=
kage rules so unnamed namespace members have internal linkage. There was on=
e terse national body comment to the effect that it's bad to have external =
linkage on things that aren't externally accessible, but otherwise the chan=
ge in direction is mysterious to me.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_FA07E357-2CF9-4604-AD91-A51AE6620062
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 8=
, 2014, at 1:11 AM, Gabriel Dos Reis &lt;<a href=3D"mailto:gdr@axiomatics.o=
rg">gdr@axiomatics.org</a>&gt; wrote:</div><br class=3D"Apple-interchange-n=
ewline"><blockquote type=3D"cite">There might be a degree of check complete=
ness, but that isn't the same<br>"compilers seldom diagnose it across TUs.&=
rdquo;</blockquote><div><br></div><div>I don&rsquo;t understand. I don&rsqu=
o;t recall ever seeing an ODR diagnosis result from LTO in particular. So f=
ar I&rsquo;ve only seen old-fashioned link errors (missing/multiply-defined=
 symbol), which are indeed a species of ODR diagnosis across TUs. But sligh=
tly mismatched inline functions such as at issue here, and similar issues, =
still fall through the cracks.</div><br><blockquote type=3D"cite">| An<br>|=
 empty class doesn't work the same way because a call to its copy<br>| cons=
tructor forms a reference -- a very minor detail no matter how you<br>| sli=
ce it.<br><br>Yes , that is low-level detail of implementation that is inci=
dental, not<br>fundamental. &nbsp;Existence of copy-constructor didn't prev=
ent constexpr<br>function to take arguments by copy even if we were careful=
 with pointers<br>and addresses.<br></blockquote><div><br></div><div>ODR-us=
e by initialization of an unused reference is a detail of normative languag=
e semantics. The low-level implementation likely doesn't care, and no diagn=
osis is required, so it tends to just work. Certainly we should be able to =
change the spec to match the solidly working implementations. The question =
is whether it&rsquo;s worthwhile to fix copy constructors in particular, or=
 go after all pass by reference functions (including perfect forwarding).</=
div><br><blockquote type=3D"cite">Because 'external' tends to be mapped to =
something at the implementation<br>detail level -- e.g. "unique address" wh=
ich can be a performance hinder<br>(think of RTTI objects for example.) &nb=
sp;Making it less relevant means that<br>it disappears from our lexicon and=
 we don't have to depend on its<br>lower-level implications.<br></blockquot=
e><div><br></div><div>Are you suggesting a stepping-stone like ambiguous li=
nkage, such as what string literals have? Note that this is what makes stri=
ngs broken as template arguments.</div><br><blockquote type=3D"cite">| And,=
 there are those who purposely use internal linkage to make names<br>| loca=
l to a TU. Why was this removed from deprecation, by the way?<br><br>I don'=
t understand this part of your message.<br></blockquote><div><br></div><div=
>In the C language, internal linkage is the only form of modular encapsulat=
ion. Private names are given internal linkage to be hidden from other TUs. =
Some folks still do this in C++.</div><div><br></div><div>C++03 deprecated =
the <font face=3D"Courier">static</font> specifier applied to namespace mem=
bers in favor of unnamed namespaces. C++11 removed the deprecation, and adj=
usted the linkage rules so unnamed namespace members have internal linkage.=
 There was one terse national body comment to the effect that it&rsquo;s ba=
d to have external linkage on things that aren&rsquo;t externally accessibl=
e, but otherwise the change in direction is mysterious to me.</div><div><br=
></div></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_FA07E357-2CF9-4604-AD91-A51AE6620062--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 8 Feb 2014 13:05:41 +0200
Raw View
On 8 February 2014 06:21, David Krauss <potswa@gmail.com> wrote:
> C++03 deprecated the static specifier applied to namespace members in favor
> of unnamed namespaces. C++11 removed the deprecation, and adjusted the
> linkage rules so unnamed namespace members have internal linkage. There was
> one terse national body comment to the effect that it's bad to have external
> linkage on things that aren't externally accessible, but otherwise the
> change in direction is mysterious to me.

I don't know which NB comment you're exactly referring to, but FI 6 on the C++0x
FCD says
" The use of static in namespace scope should not be
deprecated. Anonymous namespaces are not a sufficient
replacement for the functionality. "

Core seemed to agree on that rather quickly, without much discussion. It seemed
to me at the time that unnamed namespaces were not achieving a superior effect
in existing toolchains, and it's a C compatibility issue as well.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 8 Feb 2014 20:18:56 +0800
Raw View
On Feb 8, 2014, at 7:05 PM, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:

> I don't know which NB comment you're exactly referring to, but FI 6 on the C++0x
> FCD says
> " The use of static in namespace scope should not be
> deprecated. Anonymous namespaces are not a sufficient
> replacement for the functionality. "

Thanks! Plugging that into Google yields http://stackoverflow.com/q/8460327/153285 , which offers some insights.

It looks like the motivation for deprecation was always fairly weak compared to the desire for compatibility with "simple C" codebases.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 8 Feb 2014 14:29:01 +0200
Raw View
On 8 February 2014 14:18, David Krauss <potswa@gmail.com> wrote:
>
> On Feb 8, 2014, at 7:05 PM, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
>
>> I don't know which NB comment you're exactly referring to, but FI 6 on the C++0x
>> FCD says
>> " The use of static in namespace scope should not be
>> deprecated. Anonymous namespaces are not a sufficient
>> replacement for the functionality. "
>
> Thanks! Plugging that into Google yields http://stackoverflow.com/q/8460327/153285 , which offers some insights.
>
> It looks like the motivation for deprecation was always fairly weak compared to the desire for compatibility with "simple C" codebases.


I found a committee-internal discussion, it practically reiterated
what I summarized there.
And yes, I do recall looking at the deprecation and reacting "Whoa..
why? What's broken?
Who does this help?" :) The discussion indicated that the reasons were
weak, nothing
was broken (perhaps quite the contrary) and it seemingly didn't help anyone. :P

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 8 Feb 2014 23:12:28 +0800
Raw View
--Apple-Mail=_02E175C4-3EA9-43B1-A1C4-8810826AF873
Content-Type: text/plain; charset=ISO-8859-1


On Feb 8, 2014, at 8:29 PM, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:

> I found a committee-internal discussion, it practically reiterated
> what I summarized there.
> And yes, I do recall looking at the deprecation and reacting "Whoa..
> why? What's broken?
> Who does this help?" :) The discussion indicated that the reasons were
> weak, nothing
> was broken (perhaps quite the contrary) and it seemingly didn't help anyone. :P

Well, the problem is that if unnamed namespaces solve the same problem as internal linkage, then the two solutions are redundant. If internal linkage has no other reason to exist, then deprecating it is a simplification.

If indeed internal linkage sometimes works better than unnamed namespaces, then the latter should be fixed. Inline namespaces eliminate some differences, but the one Johannes illustrated remains, albeit with somewhat broken functionality:

namespace lib {
inline namespace v1 {

int x = 3;

} // end inline namespace v1

int x = 5; // OK, not qualified name lookup

} // end namespace lib

int q = lib::x; // Error (diagnosed by GCC, not Clang): qualified lookup finds both x's

This seems like a genuine defect: the second declaration of x should be an error because all use-cases of inline namespaces involve qualified-ids, so the declared entity is unusable.

Whether or not deprecation of internal linkage is a good goal, the notion of redundancy provides a useful viewpoint.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--Apple-Mail=_02E175C4-3EA9-43B1-A1C4-8810826AF873
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 8=
, 2014, at 8:29 PM, Ville Voutilainen &lt;<a href=3D"mailto:ville.voutilain=
en@gmail.com">ville.voutilainen@gmail.com</a>&gt; wrote:</div><br class=3D"=
Apple-interchange-newline"><blockquote type=3D"cite">I found a committee-in=
ternal discussion, it practically reiterated<br>what I summarized there.<br=
>And yes, I do recall looking at the deprecation and reacting "Whoa..<br>wh=
y? What's broken?<br>Who does this help?" :) The discussion indicated that =
the reasons were<br>weak, nothing<br>was broken (perhaps quite the contrary=
) and it seemingly didn't help anyone. :P<br></blockquote><div><br></div><d=
iv>Well, the problem is that if unnamed namespaces&nbsp;solve the same prob=
lem as internal linkage, then the two solutions are redundant. If internal =
linkage has no other reason to exist, then deprecating it is a simplificati=
on.</div><div><br></div><div>If indeed internal linkage sometimes works bet=
ter than unnamed namespaces, then the latter should be fixed. Inline namesp=
aces eliminate some differences, but the one Johannes illustrated remains, =
albeit with somewhat broken functionality:</div><div><br></div><div><font f=
ace=3D"Courier">namespace lib {</font></div><div><font face=3D"Courier">inl=
ine namespace v1 {</font></div><div><font face=3D"Courier"><br></font></div=
><div><font face=3D"Courier">int x =3D 3;</font></div><div><font face=3D"Co=
urier"><br></font></div><div><font face=3D"Courier">} // end inline namespa=
ce v1</font></div><div><font face=3D"Courier"><br></font></div><div><font f=
ace=3D"Courier">int x =3D 5; // OK, not qualified name lookup</font></div><=
div><font face=3D"Courier"><br></font></div><div><font face=3D"Courier">} /=
/ end namespace lib</font></div><div><font face=3D"Courier"><br></font></di=
v><div><font face=3D"Courier">int q =3D lib::x; // Error (diagnosed by GCC,=
 not Clang): qualified lookup finds both x&rsquo;s</font></div><div><br></d=
iv><div>This seems like a genuine defect: the second declaration of x shoul=
d be an error because all use-cases of inline namespaces involve qualified-=
ids, so the declared entity is unusable.</div><div><br></div><div>Whether o=
r not deprecation of internal linkage is a good goal, the notion of redunda=
ncy provides a useful viewpoint.</div><div><br></div></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_02E175C4-3EA9-43B1-A1C4-8810826AF873--

.