Topic: A prototype implementation of 'auto' NSDMI's for
Author: Faisal Vali <faisalv@gmail.com>
Date: Wed, 27 Nov 2013 13:13:50 -0600
Raw View
--089e013cc01ab4152604ec2d656e
Content-Type: text/plain; charset=ISO-8859-1
Hi,
Since interest in and concerns about allowing 'auto' non static data
members has been expressed (
http://accu.org/cgi-bin/wg21/message?wg=core&msg=23223 &
http://accu.org/cgi-bin/wg21/message?wg=core&msg=23496) - I thought I'd
hack together a quick implementation (based entirely on Richard smith's
Idea: http://accu.org/cgi-bin/wg21/message?wg=ext&msg=14418) to get a
better sense of some of the challenges.
What I've managed to kludge so far (and I make no claims of correctness or
viability of the approach since neither Richard nor Doug have had a chance
to review the code) is here:
-
https://github.com/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811-19-13%29
As Richard had suggested in his post, all name lookup and type deduction
for 'auto' is done at the closing brace (that is all class names have been
seen). In the clang patch above, this is done just before some semantic
checks are performed on all Field members and the class is marked
"complete" (so layout can be calculated). The auto member's initializer is
always parsed (albeit, delayed until the closing brace - but in templates
this could result in a hard error even if the initializer is not used for
initialization - but with clang this occurs even for non auto members,
right?).
The test file (to get a sense of the constructs that work) is here:
https://github.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2811-19-13%29/test/SemaCXX/cxx1z-auto-nsdmi.cpp
Essentially, things you can NOT do in the auto NSDMI
- use sizeof/alignof on the class being defined
- create an object of the type being defined
- refer to any auto members in in-class static member initializers (class
is not complete in them)
- refer to one auto member before its lexical definition in another auto
member's initializer, or in areas where the class is not marked-complete
(decltype within member function return types).
- refer to any member functions with deduced return types (although in
clang you can not do this in non-auto members currently - is this a bug or
do we intend to support:
struct X { auto f() { return 0; } int i = f(); };
Stuff you can do as long as you don't violate the above:
- refer to other members/mem_funs defined before or after the auto member
- capture 'this' in class-level lambdas.
For e.g. the following works:
struct X { //expected-note{{implicit default constructor}}
auto a1 = sizeof(this);
auto& self = *this;
auto a2 = this->mem; //expected-warning {{uninitialized}}
auto *a3 = this;
auto a4 = a3;
auto a5 = mem_fun(); // double
auto a6 = const_cast<const X*>(this)->mem_fun(); // char
auto L = [this, &r = *this, p = this] (auto a) {
return r(a, this->self, p->a2);
};
auto a7 = ([=](auto a) { return a->a1 + a1; })(this);
auto L2 = [=](auto a) { return self(a, *this, 3); };
int mem = 5;
double mem_fun() { return 3.14; }
char mem_fun() const { return 'a'; }
template<class T> bool operator()(T t, X&, int) { return true; }
};
I am quite confident there are bugs, and issues I have not thought about -
but I just wanted to see where Richard's idea could start to take us.
Any thoughts on whether it is worth spending more time on this? Any
concerns about this direction? Any obvious cases that have been overlooked?
Is there enough interest to warrant a paper (would anyone be willing to
help write one if that is the case?)
Thanks!
Faisal Vali
[I believe this certainly increases the potential for ODR-violations - but
last i heard, google was toying around with the idea of a static-analysis
tool to detect odr-violations?
http://clang-developers.42468.n3.nabble.com/design-for-an-accurate-ODR-checker-with-clang-td4033150.htmlany
updates on this?].
--
---
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/.
--089e013cc01ab4152604ec2d656e
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi,<br>=A0 Since interest in and concerns about allowing &=
#39;auto' non static data members has been expressed (<a href=3D"http:/=
/accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D23223" target=3D"_blank"=
>http://accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D23223</a> & <=
a href=3D"http://accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D23496" t=
arget=3D"_blank">http://accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D2=
3496</a>) - I thought I'd hack together a quick implementation (based e=
ntirely on Richard smith's Idea: <a href=3D"http://accu.org/cgi-bin/wg2=
1/message?wg=3Dext&msg=3D14418" target=3D"_blank">http://accu.org/cgi-b=
in/wg21/message?wg=3Dext&msg=3D14418</a>) to get a better sense of some=
of the challenges.<br>
<div><br></div>
<div>What I've managed to kludge so far (and I make no claims of correc=
tness or viability of the approach since neither Richard nor Doug have had =
a chance to review the code) is here:<br>=A0 - <a href=3D"https://github.co=
m/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811-19-13%29" target=3D"_b=
lank">https://github.com/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811=
-19-13%29</a><br>
<br></div>
<div>As Richard had suggested in his post, all name lookup and type deducti=
on for 'auto' is done at the closing brace (that is all class names=
have been seen). =A0 In the clang patch above, this is done just before so=
me semantic checks are performed on all Field members and the class is mark=
ed "complete" (so layout can be calculated).=A0 The auto member&#=
39;s initializer is always parsed =A0(albeit, delayed until the closing bra=
ce - but in templates this could result in a hard error even if the initial=
izer is not used for initialization - but with clang this occurs even for n=
on auto members, right?).<br>
<br>The test file (to get a sense of the constructs that work) is here: <br=
><a href=3D"https://github.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2=
811-19-13%29/test/SemaCXX/cxx1z-auto-nsdmi.cpp" target=3D"_blank">https://g=
ithub.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2811-19-13%29/test/Sem=
aCXX/cxx1z-auto-nsdmi.cpp</a><br>
<br>
<div>Essentially, things you can NOT do in the auto NSDMI<br></div>
<div>=A0 - use sizeof/alignof on the class being defined</div>
<div>=A0 - create an object of the type being defined<br></div>
<div>=A0 - refer to any auto members in in-class static member initializers=
(class is not complete in them)<br>=A0 - refer to one auto member before i=
ts lexical definition in another auto member's initializer, or in areas=
where the class is not marked-complete (decltype within member function re=
turn types).<br>
=A0 - refer to any member functions with deduced return types (although in =
clang you can not do this in non-auto members currently - is this a bug or =
do we intend to support:</div>
<div>=A0=A0=A0=A0 struct X { auto f() { return 0; } int i =3D f(); };<br></=
div>
<div><br>Stuff you can do as long as you don't violate the above:<br></=
div>
<div>=A0 - refer to other members/mem_funs defined before or after=A0the au=
to member=A0</div>
<div>=A0 - capture 'this' in class-level lambdas.</div>
<div>=A0</div>
<div>For e.g. the following works:</div>
<div>=A0struct X { //expected-note{{implicit default constructor}}<br>=A0=
=A0=A0 auto a1 =3D sizeof(this);<br>=A0=A0=A0 auto& self =3D *this;<br>=
=A0=A0=A0 auto a2 =3D this->mem; //expected-warning {{uninitialized}}<br=
>=A0=A0=A0 auto *a3 =3D this;<br>
=A0=A0=A0 auto a4 =3D a3;<br>=A0=A0=A0 auto a5 =3D mem_fun(); // double<br>=
=A0=A0=A0 auto a6 =3D const_cast<const X*>(this)->mem_fun(); // ch=
ar=A0 =A0<br>=A0=A0=A0 auto L =3D [this, &r =3D *this,=A0 p =3D this] (=
auto a) { <br>=A0=A0=A0=A0=A0=A0=A0=A0=A0 return r(a, this->self, p->=
a2); <br>
=A0=A0=A0 };<br>=A0=A0=A0 auto a7 =3D ([=3D](auto a) { return a->a1 + a1=
; })(this);<br>=A0=A0=A0 auto L2 =3D [=3D](auto a) { return self(a, *this, =
3); };<br>=A0=A0=A0 int mem =3D 5;<br>=A0=A0=A0 double mem_fun() { return 3=
..14; }<br>=A0=A0=A0 char mem_fun() const { return 'a'; }<br>
=A0=A0=A0 template<class T> bool operator()(T t, X&, int) { retur=
n true; }<br>=A0 };<br><br></div><div>I am quite confident there are bugs, =
and issues I have not thought about - but I just wanted to see where Richar=
d's idea could start to take us.<br>
<br>Any thoughts on whether it is worth spending more time on this? Any con=
cerns about this direction? Any obvious cases that have been overlooked? Is=
there enough interest to warrant a paper (would anyone be willing to help =
write one if that is the case?)<br>
</div><br></div><div>Thanks!<br></div>
<div><br></div>
<div>
<div>Faisal Vali<br><br>[I believe this certainly increases the potential f=
or ODR-violations
- but last i heard, google was toying around with the idea of a=20
static-analysis tool to detect odr-violations? <a href=3D"http://clang-deve=
lopers.42468.n3.nabble.com/design-for-an-accurate-ODR-checker-with-clang-td=
4033150.html" target=3D"_blank">http://clang-developers.42468.n3.nabble.com=
/design-for-an-accurate-ODR-checker-with-clang-td4033150.html</a> any updat=
es on this?].=A0 <br>
</div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--089e013cc01ab4152604ec2d656e--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 27 Nov 2013 21:31:42 +0200
Raw View
On 27 November 2013 21:13, Faisal Vali <faisalv@gmail.com> wrote:
> Any thoughts on whether it is worth spending more time on this? Any concerns
> about this direction? Any obvious cases that have been overlooked? Is there
> enough interest to warrant a paper (would anyone be willing to help write
> one if that is the case?)
+1 certainly interested in having this, willing to help with a paper.
--
---
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: Wed, 27 Nov 2013 12:54:43 -0800
Raw View
--20cf307ca44875d5ca04ec2ecea1
Content-Type: text/plain; charset=ISO-8859-1
On Wed, Nov 27, 2013 at 11:13 AM, Faisal Vali <faisalv@gmail.com> wrote:
> Hi,
> Since interest in and concerns about allowing 'auto' non static data
> members has been expressed (
> http://accu.org/cgi-bin/wg21/message?wg=core&msg=23223 &
> http://accu.org/cgi-bin/wg21/message?wg=core&msg=23496) - I thought I'd
> hack together a quick implementation (based entirely on Richard smith's
> Idea: http://accu.org/cgi-bin/wg21/message?wg=ext&msg=14418) to get a
> better sense of some of the challenges.
>
> What I've managed to kludge so far (and I make no claims of correctness or
> viability of the approach since neither Richard nor Doug have had a chance
> to review the code) is here:
> -
> https://github.com/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811-19-13%29
>
> As Richard had suggested in his post, all name lookup and type deduction
> for 'auto' is done at the closing brace (that is all class names have been
> seen). In the clang patch above, this is done just before some semantic
> checks are performed on all Field members and the class is marked
> "complete" (so layout can be calculated). The auto member's initializer is
> always parsed (albeit, delayed until the closing brace - but in templates
> this could result in a hard error even if the initializer is not used for
> initialization - but with clang this occurs even for non auto members,
> right?).
>
It does, but per discussion in core, it should not -- default initializers
should only be instantiated when they're needed (see core issue 1396). I
don't see a problem with eagerly instantiating them when we complete the
class, for each non-static data member whose type contains a placeholder.
> The test file (to get a sense of the constructs that work) is here:
>
> https://github.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2811-19-13%29/test/SemaCXX/cxx1z-auto-nsdmi.cpp
>
> Essentially, things you can NOT do in the auto NSDMI
> - use sizeof/alignof on the class being defined
> - create an object of the type being defined
> - refer to any auto members in in-class static member initializers
> (class is not complete in them)
> - refer to one auto member before its lexical definition in another auto
> member's initializer, or in areas where the class is not marked-complete
> (decltype within member function return types).
> - refer to any member functions with deduced return types (although in
> clang you can not do this in non-auto members currently - is this a bug or
> do we intend to support:
> struct X { auto f() { return 0; } int i = f(); };
>
This is a very messy area; the core language doesn't specify the
circumstances under which one delay-parsed entity can refer to another
(this shows up in a number of other guises, such as calling a constexpr
function in a constant expression in an exception specification, or calling
a function with a deduced return type in a default argument). Last time I
looked at this, each compiler did something different here. This seems
worthy of a core issue.
> Stuff you can do as long as you don't violate the above:
> - refer to other members/mem_funs defined before or after the auto
> member
> - capture 'this' in class-level lambdas.
>
> For e.g. the following works:
> struct X { //expected-note{{implicit default constructor}}
> auto a1 = sizeof(this);
> auto& self = *this;
> auto a2 = this->mem; //expected-warning {{uninitialized}}
> auto *a3 = this;
> auto a4 = a3;
> auto a5 = mem_fun(); // double
> auto a6 = const_cast<const X*>(this)->mem_fun(); // char
> auto L = [this, &r = *this, p = this] (auto a) {
> return r(a, this->self, p->a2);
> };
> auto a7 = ([=](auto a) { return a->a1 + a1; })(this);
> auto L2 = [=](auto a) { return self(a, *this, 3); };
> int mem = 5;
> double mem_fun() { return 3.14; }
> char mem_fun() const { return 'a'; }
> template<class T> bool operator()(T t, X&, int) { return true; }
> };
>
> I am quite confident there are bugs, and issues I have not thought about -
> but I just wanted to see where Richard's idea could start to take us.
>
Is the class regarded as complete when you parse the default initializers?
If so, what happens if one of them requires knowledge of the class layout?
For instance:
template<int> struct something { typedef int type; };
struct A {
int x;
auto y = something<offsetof(A, z)>::type(); // will need layout here
int z;
};
.... or ...
template<int*> struct something { typedef int type; };
template<typename T> auto stuff() {
static T t;
constexpr int *p = &t.z; // may need layout here
return typename something<p>::type();
}
struct A {
int x;
auto y = stuff<A>();
int z;
};
Any thoughts on whether it is worth spending more time on this? Any
> concerns about this direction? Any obvious cases that have been overlooked?
> Is there enough interest to warrant a paper (would anyone be willing to
> help write one if that is the case?)
>
> Thanks!
>
> Faisal Vali
>
> [I believe this certainly increases the potential for ODR-violations - but
> last i heard, google was toying around with the idea of a static-analysis
> tool to detect odr-violations?
> http://clang-developers.42468.n3.nabble.com/design-for-an-accurate-ODR-checker-with-clang-td4033150.htmlany updates on this?].
>
> --
>
> ---
> 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/.
--20cf307ca44875d5ca04ec2ecea1
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wed, Nov 27, 2013 at 11:13 AM, Faisal Vali <span dir=3D=
"ltr"><<a href=3D"mailto:faisalv@gmail.com" target=3D"_blank">faisalv@gm=
ail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"g=
mail_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 dir=3D"ltr">Hi,<br>=A0 Since interest in and concerns=
about allowing 'auto' non static data members has been expressed (=
<a href=3D"http://accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D23223" =
target=3D"_blank">http://accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D=
23223</a> & <a href=3D"http://accu.org/cgi-bin/wg21/message?wg=3Dcore&a=
mp;msg=3D23496" target=3D"_blank">http://accu.org/cgi-bin/wg21/message?wg=
=3Dcore&msg=3D23496</a>) - I thought I'd hack together a quick impl=
ementation (based entirely on Richard smith's Idea: <a href=3D"http://a=
ccu.org/cgi-bin/wg21/message?wg=3Dext&msg=3D14418" target=3D"_blank">ht=
tp://accu.org/cgi-bin/wg21/message?wg=3Dext&msg=3D14418</a>) to get a b=
etter sense of some of the challenges.<br>
<div><br></div>
<div>What I've managed to kludge so far (and I make no claims of correc=
tness or viability of the approach since neither Richard nor Doug have had =
a chance to review the code) is here:<br>=A0 - <a href=3D"https://github.co=
m/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811-19-13%29" target=3D"_b=
lank">https://github.com/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811=
-19-13%29</a><br>
<br></div>
<div>As Richard had suggested in his post, all name lookup and type deducti=
on for 'auto' is done at the closing brace (that is all class names=
have been seen). =A0 In the clang patch above, this is done just before so=
me semantic checks are performed on all Field members and the class is mark=
ed "complete" (so layout can be calculated).=A0 The auto member&#=
39;s initializer is always parsed =A0(albeit, delayed until the closing bra=
ce - but in templates this could result in a hard error even if the initial=
izer is not used for initialization - but with clang this occurs even for n=
on auto members, right?).<br>
</div></div></blockquote><div><br></div><div>It does, but per discussion in=
core, it should not -- default initializers should only be instantiated wh=
en they're needed (see core issue 1396). I don't see a problem with=
eagerly instantiating them when we complete the class, for each non-static=
data member whose type contains a placeholder.</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 dir=3D"ltr"><div>The test file (to get =
a sense of the constructs that work) is here: <br>
<a href=3D"https://github.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%28=
11-19-13%29/test/SemaCXX/cxx1z-auto-nsdmi.cpp" target=3D"_blank">https://gi=
thub.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2811-19-13%29/test/Sema=
CXX/cxx1z-auto-nsdmi.cpp</a><br>
<br>
<div>Essentially, things you can NOT do in the auto NSDMI<br></div>
<div>=A0 - use sizeof/alignof on the class being defined</div>
<div>=A0 - create an object of the type being defined<br></div>
<div>=A0 - refer to any auto members in in-class static member initializers=
(class is not complete in them)<br>=A0 - refer to one auto member before i=
ts lexical definition in another auto member's initializer, or in areas=
where the class is not marked-complete (decltype within member function re=
turn types).<br>
=A0 - refer to any member functions with deduced return types (although in =
clang you can not do this in non-auto members currently - is this a bug or =
do we intend to support:</div>
<div>=A0=A0=A0=A0 struct X { auto f() { return 0; } int i =3D f(); };</div>=
</div></div></blockquote><div><br></div><div>This is a very messy area; the=
core language doesn't specify the circumstances under which one delay-=
parsed entity can refer to another (this shows up in a number of other guis=
es, such as calling a constexpr function in a constant expression in an exc=
eption specification, or calling a function with a deduced return type in a=
default argument). Last time I looked at this, each compiler did something=
different here. This seems worthy of 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"><div dir=3D"ltr"><div><div>Stuff you can do =
as long as you don't violate the above:<br>
</div>
<div>=A0 - refer to other members/mem_funs defined before or after=A0the au=
to member=A0</div>
<div>=A0 - capture 'this' in class-level lambdas.</div>
<div>=A0</div>
<div>For e.g. the following works:</div>
<div>=A0struct X { //expected-note{{implicit default constructor}}<br>=A0=
=A0=A0 auto a1 =3D sizeof(this);<br>=A0=A0=A0 auto& self =3D *this;<br>=
=A0=A0=A0 auto a2 =3D this->mem; //expected-warning {{uninitialized}}<br=
>=A0=A0=A0 auto *a3 =3D this;<br>
=A0=A0=A0 auto a4 =3D a3;<br>=A0=A0=A0 auto a5 =3D mem_fun(); // double<br>=
=A0=A0=A0 auto a6 =3D const_cast<const X*>(this)->mem_fun(); // ch=
ar=A0 =A0<br>=A0=A0=A0 auto L =3D [this, &r =3D *this,=A0 p =3D this] (=
auto a) { <br>=A0=A0=A0=A0=A0=A0=A0=A0=A0 return r(a, this->self, p->=
a2); <br>
=A0=A0=A0 };<br>=A0=A0=A0 auto a7 =3D ([=3D](auto a) { return a->a1 + a1=
; })(this);<br>=A0=A0=A0 auto L2 =3D [=3D](auto a) { return self(a, *this, =
3); };<br>=A0=A0=A0 int mem =3D 5;<br>=A0=A0=A0 double mem_fun() { return 3=
..14; }<br>=A0=A0=A0 char mem_fun() const { return 'a'; }<br>
=A0=A0=A0 template<class T> bool operator()(T t, X&, int) { retur=
n true; }<br>=A0 };<br><br></div><div>I am quite confident there are bugs, =
and issues I have not thought about - but I just wanted to see where Richar=
d's idea could start to take us.<br>
</div></div></div></blockquote><div><br></div><div>Is the class regarded as=
complete when you parse the default initializers? If so, what happens if o=
ne of them requires knowledge of the class layout? For instance:</div><div>
<br></div><div>template<int> struct something { typedef int type; };<=
/div><div><br></div><div>struct A {</div><div>=A0 int x;</div><div>=A0 auto=
y =3D something<offsetof(A, z)>::type(); // will need layout here</d=
iv>
<div>=A0 int z;</div><div>};</div><div><br></div><div>... or ...</div><div>=
<br></div><div>template<int*> struct something { typedef int type; };=
</div><div><br></div><div>template<typename T> auto stuff() {</div>
<div>=A0 static T t;</div><div>=A0 constexpr int *p =3D &t.z; // may ne=
ed layout here</div><div>=A0 return typename something<p>::type();</d=
iv><div>}</div><div><br></div><div>struct A {</div><div>=A0 int x;</div><di=
v>=A0 auto y =3D stuff<A>();</div>
<div>=A0 int z;<br>};</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 dir=3D"ltr"=
><div>
<div>Any thoughts on whether it is worth spending more time on this? Any co=
ncerns about this direction? Any obvious cases that have been overlooked? I=
s there enough interest to warrant a paper (would anyone be willing to help=
write one if that is the case?)<br>
</div><br></div><div>Thanks!<br></div>
<div><br></div>
<div>
<div>Faisal Vali<br><br>[I believe this certainly increases the potential f=
or ODR-violations
- but last i heard, google was toying around with the idea of a=20
static-analysis tool to detect odr-violations? <a href=3D"http://clang-deve=
lopers.42468.n3.nabble.com/design-for-an-accurate-ODR-checker-with-clang-td=
4033150.html" target=3D"_blank">http://clang-developers.42468.n3.nabble.com=
/design-for-an-accurate-ODR-checker-with-clang-td4033150.html</a> any updat=
es on this?].=A0 <br>
<span class=3D""><font color=3D"#888888">
</font></span></div></div></div><span class=3D""><font color=3D"#888888">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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>
</font></span></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--20cf307ca44875d5ca04ec2ecea1--
.
Author: Faisal Vali <faisalv@gmail.com>
Date: Wed, 27 Nov 2013 15:22:21 -0600
Raw View
--047d7b41432448cc4204ec2f3196
Content-Type: text/plain; charset=ISO-8859-1
On Wed, Nov 27, 2013 at 2:54 PM, Richard Smith <richard@metafoo.co.uk>wrote:
> On Wed, Nov 27, 2013 at 11:13 AM, Faisal Vali <faisalv@gmail.com> wrote:
>
>> Hi,
>> Since interest in and concerns about allowing 'auto' non static data
>> members has been expressed (
>> http://accu.org/cgi-bin/wg21/message?wg=core&msg=23223 &
>> http://accu.org/cgi-bin/wg21/message?wg=core&msg=23496) - I thought I'd
>> hack together a quick implementation (based entirely on Richard smith's
>> Idea: http://accu.org/cgi-bin/wg21/message?wg=ext&msg=14418) to get a
>> better sense of some of the challenges.
>>
>> What I've managed to kludge so far (and I make no claims of correctness
>> or viability of the approach since neither Richard nor Doug have had a
>> chance to review the code) is here:
>> -
>> https://github.com/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811-19-13%29
>>
>> As Richard had suggested in his post, all name lookup and type deduction
>> for 'auto' is done at the closing brace (that is all class names have been
>> seen). In the clang patch above, this is done just before some semantic
>> checks are performed on all Field members and the class is marked
>> "complete" (so layout can be calculated). The auto member's initializer is
>> always parsed (albeit, delayed until the closing brace - but in templates
>> this could result in a hard error even if the initializer is not used for
>> initialization - but with clang this occurs even for non auto members,
>> right?).
>>
>
> It does, but per discussion in core, it should not -- default initializers
> should only be instantiated when they're needed (see core issue 1396). I
> don't see a problem with eagerly instantiating them when we complete the
> class, for each non-static data member whose type contains a placeholder.
>
>
>> The test file (to get a sense of the constructs that work) is here:
>>
>> https://github.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2811-19-13%29/test/SemaCXX/cxx1z-auto-nsdmi.cpp
>>
>> Essentially, things you can NOT do in the auto NSDMI
>> - use sizeof/alignof on the class being defined
>> - create an object of the type being defined
>> - refer to any auto members in in-class static member initializers
>> (class is not complete in them)
>> - refer to one auto member before its lexical definition in another
>> auto member's initializer, or in areas where the class is not
>> marked-complete (decltype within member function return types).
>> - refer to any member functions with deduced return types (although in
>> clang you can not do this in non-auto members currently - is this a bug or
>> do we intend to support:
>> struct X { auto f() { return 0; } int i = f(); };
>>
>
> This is a very messy area; the core language doesn't specify the
> circumstances under which one delay-parsed entity can refer to another
> (this shows up in a number of other guises, such as calling a constexpr
> function in a constant expression in an exception specification, or calling
> a function with a deduced return type in a default argument). Last time I
> looked at this, each compiler did something different here. This seems
> worthy of a core issue.
>
>
>> Stuff you can do as long as you don't violate the above:
>> - refer to other members/mem_funs defined before or after the auto
>> member
>> - capture 'this' in class-level lambdas.
>>
>> For e.g. the following works:
>> struct X { //expected-note{{implicit default constructor}}
>> auto a1 = sizeof(this);
>> auto& self = *this;
>> auto a2 = this->mem; //expected-warning {{uninitialized}}
>> auto *a3 = this;
>> auto a4 = a3;
>> auto a5 = mem_fun(); // double
>> auto a6 = const_cast<const X*>(this)->mem_fun(); // char
>> auto L = [this, &r = *this, p = this] (auto a) {
>> return r(a, this->self, p->a2);
>> };
>> auto a7 = ([=](auto a) { return a->a1 + a1; })(this);
>> auto L2 = [=](auto a) { return self(a, *this, 3); };
>> int mem = 5;
>> double mem_fun() { return 3.14; }
>> char mem_fun() const { return 'a'; }
>> template<class T> bool operator()(T t, X&, int) { return true; }
>> };
>>
>> I am quite confident there are bugs, and issues I have not thought about
>> - but I just wanted to see where Richard's idea could start to take us.
>>
>
> Is the class regarded as complete when you parse the default initializers?
> If so, what happens if one of them requires knowledge of the class layout?
> For instance:
>
>
It is regarded as complete for purposes of layout when you parse non auto
default initializers - but not complete for purposes of layout when you are
parsing default initializers for auto members (although the
sema::ActOnCXXInClassMemberInitializer hook, which checks the
initialization conversions, lval-to-rval etc. is done once the class is
marked complete, with the rest of the fields, in the order they were all
declared).
> template<int> struct something { typedef int type; };
>
> struct A {
> int x;
> auto y = something<offsetof(A, z)>::type(); // will need layout here
> int z;
> };
>
> ... or ...
>
> template<int*> struct something { typedef int type; };
>
> template<typename T> auto stuff() {
> static T t;
> constexpr int *p = &t.z; // may need layout here
> return typename something<p>::type();
> }
>
> struct A {
> int x;
> auto y = stuff<A>();
> int z;
> };
>
>
Your examples generate the following error messages:
template<int*> struct something { typedef int type; };
template<typename T> auto stuff() {
static T t; //expected-error{{incomplete type}}
constexpr int *p = &t.z; // may need layout here
return typename something<p>::type();
}
struct A { //expected-note{{not complete}}
int x;
auto y = stuff<A>(); //expected-note{{instantiation}}
int z;
};
namespace offsetof_test {
#define offsetof(t, d) __builtin_offsetof(t, d)
template<int> struct something { typedef int type; };
struct A { //expected-note{{not complete}}
int x;
auto y = something<offsetof(A, z)>::type{}; //expected-error{{incomplete
type}}\
//expected-error{{expected ';'}}
int z;
};
}
thanks!
> Any thoughts on whether it is worth spending more time on this? Any
>> concerns about this direction? Any obvious cases that have been overlooked?
>> Is there enough interest to warrant a paper (would anyone be willing to
>> help write one if that is the case?)
>>
>> Thanks!
>>
>> Faisal Vali
>>
>> [I believe this certainly increases the potential for ODR-violations -
>> but last i heard, google was toying around with the idea of a
>> static-analysis tool to detect odr-violations?
>> http://clang-developers.42468.n3.nabble.com/design-for-an-accurate-ODR-checker-with-clang-td4033150.htmlany updates on this?].
>>
>> --
>>
>> ---
>> 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/.
>
--
---
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/.
--047d7b41432448cc4204ec2f3196
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, Nov 27, 2013 at 2:54 PM, Richard Smith <span dir=3D"ltr"><<a=
href=3D"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co=
..uk</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div cla=
ss=3D"im">On Wed, Nov 27, 2013 at 11:13 AM, Faisal Vali <span dir=3D"ltr">&=
lt;<a href=3D"mailto:faisalv@gmail.com" target=3D"_blank">faisalv@gmail.com=
</a>></span> wrote:<br>
</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D"i=
m">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">Hi,<br>=
=A0 Since interest in and concerns about allowing 'auto' non static=
data members has been expressed (<a href=3D"http://accu.org/cgi-bin/wg21/m=
essage?wg=3Dcore&msg=3D23223" target=3D"_blank">http://accu.org/cgi-bin=
/wg21/message?wg=3Dcore&msg=3D23223</a> & <a href=3D"http://accu.or=
g/cgi-bin/wg21/message?wg=3Dcore&msg=3D23496" target=3D"_blank">http://=
accu.org/cgi-bin/wg21/message?wg=3Dcore&msg=3D23496</a>) - I thought I&=
#39;d hack together a quick implementation (based entirely on Richard smith=
's Idea: <a href=3D"http://accu.org/cgi-bin/wg21/message?wg=3Dext&m=
sg=3D14418" target=3D"_blank">http://accu.org/cgi-bin/wg21/message?wg=3Dext=
&msg=3D14418</a>) to get a better sense of some of the challenges.<br>
<div><br></div>
<div>What I've managed to kludge so far (and I make no claims of correc=
tness or viability of the approach since neither Richard nor Doug have had =
a chance to review the code) is here:<br>=A0 - <a href=3D"https://github.co=
m/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811-19-13%29" target=3D"_b=
lank">https://github.com/faisalv/clang/commits/auto-nsdmi-llvm-r195138%2811=
-19-13%29</a><br>
<br></div>
<div>As Richard had suggested in his post, all name lookup and type deducti=
on for 'auto' is done at the closing brace (that is all class names=
have been seen). =A0 In the clang patch above, this is done just before so=
me semantic checks are performed on all Field members and the class is mark=
ed "complete" (so layout can be calculated).=A0 The auto member&#=
39;s initializer is always parsed =A0(albeit, delayed until the closing bra=
ce - but in templates this could result in a hard error even if the initial=
izer is not used for initialization - but with clang this occurs even for n=
on auto members, right?).<br>
</div></div></blockquote><div><br></div></div><div>It does, but per discuss=
ion in core, it should not -- default initializers should only be instantia=
ted when they're needed (see core issue 1396). I don't see a proble=
m with eagerly instantiating them when we complete the class, for each non-=
static data member whose type contains a placeholder.</div>
<div class=3D"im">
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D=
"ltr"><div>The test file (to get a sense of the constructs that work) is he=
re: <br>
<a href=3D"https://github.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%28=
11-19-13%29/test/SemaCXX/cxx1z-auto-nsdmi.cpp" target=3D"_blank">https://gi=
thub.com/faisalv/clang/blob/auto-nsdmi-llvm-r195138%2811-19-13%29/test/Sema=
CXX/cxx1z-auto-nsdmi.cpp</a><br>
<br>
<div>Essentially, things you can NOT do in the auto NSDMI<br></div>
<div>=A0 - use sizeof/alignof on the class being defined</div>
<div>=A0 - create an object of the type being defined<br></div>
<div>=A0 - refer to any auto members in in-class static member initializers=
(class is not complete in them)<br>=A0 - refer to one auto member before i=
ts lexical definition in another auto member's initializer, or in areas=
where the class is not marked-complete (decltype within member function re=
turn types).<br>
=A0 - refer to any member functions with deduced return types (although in =
clang you can not do this in non-auto members currently - is this a bug or =
do we intend to support:</div>
<div>=A0=A0=A0=A0 struct X { auto f() { return 0; } int i =3D f(); };</div>=
</div></div></blockquote><div><br></div></div><div>This is a very messy are=
a; the core language doesn't specify the circumstances under which one =
delay-parsed entity can refer to another (this shows up in a number of othe=
r guises, such as calling a constexpr function in a constant expression in =
an exception specification, or calling a function with a deduced return typ=
e in a default argument). Last time I looked at this, each compiler did som=
ething different here. This seems worthy of a core issue.</div>
<div class=3D"im">
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D=
"ltr"><div><div>Stuff you can do as long as you don't violate the above=
:<br>
</div>
<div>=A0 - refer to other members/mem_funs defined before or after=A0the au=
to member=A0</div>
<div>=A0 - capture 'this' in class-level lambdas.</div>
<div>=A0</div>
<div>For e.g. the following works:</div>
<div>=A0struct X { //expected-note{{implicit default constructor}}<br>=A0=
=A0=A0 auto a1 =3D sizeof(this);<br>=A0=A0=A0 auto& self =3D *this;<br>=
=A0=A0=A0 auto a2 =3D this->mem; //expected-warning {{uninitialized}}<br=
>=A0=A0=A0 auto *a3 =3D this;<br>
=A0=A0=A0 auto a4 =3D a3;<br>=A0=A0=A0 auto a5 =3D mem_fun(); // double<br>=
=A0=A0=A0 auto a6 =3D const_cast<const X*>(this)->mem_fun(); // ch=
ar=A0 =A0<br>=A0=A0=A0 auto L =3D [this, &r =3D *this,=A0 p =3D this] (=
auto a) { <br>=A0=A0=A0=A0=A0=A0=A0=A0=A0 return r(a, this->self, p->=
a2); <br>
=A0=A0=A0 };<br>=A0=A0=A0 auto a7 =3D ([=3D](auto a) { return a->a1 + a1=
; })(this);<br>=A0=A0=A0 auto L2 =3D [=3D](auto a) { return self(a, *this, =
3); };<br>=A0=A0=A0 int mem =3D 5;<br>=A0=A0=A0 double mem_fun() { return 3=
..14; }<br>=A0=A0=A0 char mem_fun() const { return 'a'; }<br>
=A0=A0=A0 template<class T> bool operator()(T t, X&, int) { retur=
n true; }<br>=A0 };<br><br></div><div>I am quite confident there are bugs, =
and issues I have not thought about - but I just wanted to see where Richar=
d's idea could start to take us.<br>
</div></div></div></blockquote><div><br></div></div><div>Is the class regar=
ded as complete when you parse the default initializers? If so, what happen=
s if one of them requires knowledge of the class layout? For instance:</div=
>
<div>
<br></div></div></div></div></blockquote><div><br></div><div>It is regarded=
as complete for purposes of layout when you parse non auto default initial=
izers - but not complete for purposes of layout when you are parsing defaul=
t initializers for auto members (although the sema::ActOnCXXInClassMemberIn=
itializer hook, which checks the initialization conversions, lval-to-rval e=
tc. is done once the class is marked complete, with the rest of the fields,=
in the order they were all declared).<br>
</div><div><br>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>=
</div><div>
template<int> struct something { typedef int type; };</div><div><br><=
/div><div>struct A {</div><div>=A0 int x;</div><div>=A0 auto y =3D somethin=
g<offsetof(A, z)>::type(); // will need layout here</div>
<div>=A0 int z;</div><div>};</div><div><br></div><div>... or ...</div><div>=
<br></div><div>template<int*> struct something { typedef int type; };=
</div><div><br></div><div>template<typename T> auto stuff() {</div>
<div>=A0 static T t;</div><div>=A0 constexpr int *p =3D &t.z; // may ne=
ed layout here</div><div>=A0 return typename something<p>::type();</d=
iv><div>}</div><div><br></div><div>struct A {</div><div>=A0 int x;</div><di=
v>=A0 auto y =3D stuff<A>();</div>
<div>=A0 int z;<br>};</div><div><br></div></div></div></div></blockquote><d=
iv><br></div><div>Your examples generate the following error messages:<br>t=
emplate<int*> struct something { typedef int type; };<br><br>template=
<typename T> auto stuff() {<br>
=A0 static T t;=A0 //expected-error{{incomplete type}}<br>=A0 constexpr int=
*p =3D &t.z; // may need layout here<br>=A0 return typename something&=
lt;p>::type();<br>}<br><br>struct A { //expected-note{{not complete}}<br=
>=A0 int x;<br>
=A0 auto y =3D stuff<A>(); //expected-note{{instantiation}}<br>=A0 in=
t z;<br>};<br>namespace offsetof_test {<br><br>#define offsetof(t,=A0 d) __=
builtin_offsetof(t, d) <br><br>template<int> struct something { typed=
ef int type; };<br>
<br>struct A { //expected-note{{not complete}}<br>=A0 int x;<br>=A0 auto y =
=3D something<offsetof(A, z)>::type{}; //expected-error{{incomplete t=
ype}}\<br>=A0=A0=A0=A0=A0=A0=A0 //expected-error{{expected ';'}}<br=
>=A0 int z;<br>};<br>
<br>}<br></div><div><br></div><div>thanks!<br></div><div><br><br>=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div clas=
s=3D"gmail_extra">
<div class=3D"gmail_quote"><div></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex"><div class=3D"im"><div dir=3D"ltr"><div>
<div>Any thoughts on whether it is worth spending more time on this? Any co=
ncerns about this direction? Any obvious cases that have been overlooked? I=
s there enough interest to warrant a paper (would anyone be willing to help=
write one if that is the case?)<br>
</div><br></div><div>Thanks!<br></div>
<div><br></div>
<div>
<div>Faisal Vali<br><br>[I believe this certainly increases the potential f=
or ODR-violations
- but last i heard, google was toying around with the idea of a=20
static-analysis tool to detect odr-violations? <a href=3D"http://clang-deve=
lopers.42468.n3.nabble.com/design-for-an-accurate-ODR-checker-with-clang-td=
4033150.html" target=3D"_blank">http://clang-developers.42468.n3.nabble.com=
/design-for-an-accurate-ODR-checker-with-clang-td4033150.html</a> any updat=
es on this?].=A0 <br>
<span><font color=3D"#888888">
</font></span></div></div></div></div><span><font color=3D"#888888">
<p></p>
-- <br><div class=3D"im">
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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></font></span></blockquote></div><br></div></div><div class=3D""><div=
class=3D"h5">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--047d7b41432448cc4204ec2f3196--
.