Topic: Implementability of std::optional


Author: Nikolay Ivchenkov <mk.ivchenkov@gmail.com>
Date: Fri, 31 May 2013 05:48:11 -0700 (PDT)
Raw View
------=_Part_41_24142763.1370004491584
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

[This thread is based on the recent discussion "Implementation of=20
assignment in std::optional and Core issue 1404: Object reallocation in=20
unions" on SG12 reflector (about undefined/unspecified behavior)].

----------------------------------------------------------------------

The following concerns are related to the suggested implementation of=20
optional - see
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3672.html
https://github.com/akrzemi1/Optional/blob/master/optional.hpp

Consider the following example:

    #include "optional.hpp"
    #include <iostream>

    struct A
    {
        constexpr A(int &x) : ref(x) {}
        int &ref;
    };

    int main()
    {
        int n1 =3D 0, n2 =3D 0;
        std::experimental::optional<A> opt =3D A(n1);
        opt.emplace(n2);
        opt->ref =3D 1;
        std::cout << n1 << " " << n2 << std::endl;
    }

Here initialization of variable opt implies initialization of union member=
=20
storage_.value_ (which has type A). Then expression opt.emplace(n2)destroys=
 object=20
storage_.value_ via explicit destructor call and creates new object by=20
placement form of new-expression (using forwarded n2 in the=20
new-initializer). All public functions that provide access to the stored=20
value (operator->(), operator *(), value(), etc.), obtain pointer/reference=
=20
through object expression storage_.value_.

This is a simplified version of the above code:

    #include <iostream>

    #define FORWARD(x) static_cast<decltype(x) &&>(x)

    template <class T>
        union U
    {
        constexpr U(T &&x) : value_(FORWARD(x)) {}
        unsigned char dummy_;
        T value_;
    };

    template <class T>
        struct optional
    {
        constexpr optional(T &&x) : storage_(FORWARD(x)) {}
        template <class... Params>
            void emplace(Params &&... params)
        {
            storage_.value_.~T();
            new (&storage_.value_) T(FORWARD(params)...);
        }

        U<T> storage_;
    };

    struct A
    {
        constexpr A(int &x) : ref(x) {}
        int &ref;
    };

    int main()
    {
        int n1 =3D 0, n2 =3D 0;
        optional<A> opt2 =3D A(n1);
        opt2.emplace(n2);
        opt2.storage_.value_.ref =3D 1;
        std::cout << n1 << " " << n2 << std::endl;
    }

The question is: What may happen at line

    opt->ref =3D 1;

in the former code or

    opt2.storage_.value_.ref =3D 1;

in the latter (simplified) code?

According to N3485 - 3.8/7,

    If, after the lifetime of an object has ended and before the
    storage which the object occupied is reused or released, a new
    object is created at the storage location which the original
    object occupied, a pointer that pointed to the original object, a
    reference that referred to the original object, or the name of the
    original object will automatically refer to the new object and,
    once the lifetime of the new object has started, can be used to
    manipulate the new object, if:

    [...]
    =97 the type of the original object is not const-qualified, and, if
      a class type, does not contain any non-static data member whose
      type is const-qualified or a reference type, and
    [...]

In our case the cited condition is not satisfied, because A has a=20
non-static data member of a reference type =97 ref.

I presume that the intention behind 3.8/7 was to allow optimizations=20
described below:

    #include <iostream>

    struct X
    {
        int &ref;
    };

    void f(X &);

    int main()
    {
        int n =3D 0;
        X x{n};
        f(x);
        x.ref =3D 5;
        std::cout << n << std::endl;
    }

Here a compiler is allowed to assume that

    x.ref =3D 5;

is equivalent to

    n =3D 5;

and therefore

    std::cout << n << std::endl;

is equivalent to

    std::cout << 5 << std::endl;

regardless of the definition of f (which may be unknown for compiler).=20
There is no legal way to modify reference x.ref after its initialization so=
=20
that it would refer to a different location. Even if we overwrite the=20
storage of x by construction of a new object of type X at address &x (our=
=20
mysterious f could do such thing), a compiler may assume that reference=20
x.ref is untouched.

The same applies to the original example with optional: it looks like a=20
compiler is free to assume that opt->ref or opt2.storage_.value_.ref still=
=20
refers to n1 (as if the accessed ref would be member of the old object)=20
rather than n2 (to which new ref is supposed to refer). Such a behavior may=
=20
be unexpected for some programmers.

There are several ways to handle the issue. It's possible to:

1) reflect the limitations of the suggested implementation in the=20
specification of std::optional;

2) find a reliable portable (and potentially less effective) implementation=
=20
without limitations regarding to members of reference/const-qualified types=
;

3) acknowledge that an effective implementation of std::optional should=20
rely on some compiler-specific behavior in order to avoid troubles with=20
members of reference/const-qualified types;

4) make two templates: std::optional (which can use std::aligned_storage)=
=20
with normal support of assignment but without support of constexpr=20
semantics, and std::literal_optional (which can use unions in order to=20
implement constexpr semantics);

5) introduce special rules for union members in order to make such tricks=
=20
with unions well-defined;

6) reconsider the existing core rules in 3.8/7 more widely (not only with=
=20
regard to unions).

There may be other options. Which direction is the most preferable?

--=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/?hl=3Den.



------=_Part_41_24142763.1370004491584
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

[This thread is based on the recent discussion "Implementation of assignmen=
t in std::optional and Core issue 1404: Object reallocation in unions" on S=
G12 reflector (about undefined/unspecified behavior)].<br><br>-------------=
---------------------------------------------------------<br><br>The follow=
ing concerns are related to the suggested implementation of optional - see<=
br>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3672.html<br>ht=
tps://github.com/akrzemi1/Optional/blob/master/optional.hpp<br><br>Consider=
 the following example:<br><br><span style=3D"font-family: courier new,mono=
space;">&nbsp;&nbsp;&nbsp; #include "optional.hpp"<br>&nbsp;&nbsp;&nbsp; #i=
nclude &lt;iostream&gt;<br><br>&nbsp;&nbsp;&nbsp; struct A<br>&nbsp;&nbsp;&=
nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constexpr A(int &amp;=
x) : ref(x) {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int &amp;ref;<=
br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; int main()<br>&nbsp;&nbs=
p;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int n1 =3D 0, n2 =
=3D 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::experimental::opt=
ional&lt;A&gt; opt =3D A(n1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 opt.emplace(n2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opt-&gt;ref=
 =3D 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; n1=
 &lt;&lt; " " &lt;&lt; n2 &lt;&lt; std::endl;<br>&nbsp;&nbsp;&nbsp; }</span=
><br><br>Here initialization of variable opt implies initialization of unio=
n member <span style=3D"font-family: courier new,monospace;">storage_.value=
_</span> (which has type A). Then expression <span style=3D"font-family: co=
urier new,monospace;">opt.emplace(n2)</span> destroys object <span style=3D=
"font-family: courier new,monospace;">storage_.value_</span> via explicit d=
estructor call and creates new object by placement form of new-expression (=
using forwarded n2 in the new-initializer). All public functions that provi=
de access to the stored value (operator-&gt;(), operator *(), value(), etc.=
), obtain pointer/reference through object expression <span style=3D"font-f=
amily: courier new,monospace;">storage_.value_</span>.<br><br>This is a sim=
plified version of the above code:<br><br><span style=3D"font-family: couri=
er new,monospace;">&nbsp;&nbsp;&nbsp; #include &lt;iostream&gt;<br><br>&nbs=
p;&nbsp;&nbsp; #define FORWARD(x) static_cast&lt;decltype(x) &amp;&amp;&gt;=
(x)<br><br>&nbsp;&nbsp;&nbsp; template &lt;class T&gt;<br>&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp; union U<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; constexpr U(T &amp;&amp;x) : value_(FORWARD(x)=
) {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char dummy_;<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T value_;<br>&nbsp;&nbsp;&nbsp;=
 };<br><br>&nbsp;&nbsp;&nbsp; template &lt;class T&gt;<br>&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp; struct optional<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constexpr optional(T &amp;&amp;x) : st=
orage_(FORWARD(x)) {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; templat=
e &lt;class... Params&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp; void emplace(Params &amp;&amp;... params)<br>&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; storage_.value_.~T();<br>&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new (&amp;storage_.value_) =
T(FORWARD(params)...);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><=
br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; U&lt;T&gt; storage_;<br>&nbsp=
;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; struct A<br>&nbsp;&nbsp;&nbsp; {=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constexpr A(int &amp;x) : re=
f(x) {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int &amp;ref;<br>&nbs=
p;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; int main()<br>&nbsp;&nbsp;&nbsp=
; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int n1 =3D 0, n2 =3D 0;<b=
r>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; optional&lt;A&gt; opt2 =3D A(n=
1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opt2.emplace(n2);<br>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opt2.storage_.value_.ref =3D 1;<br>&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; n1 &lt;&lt; " =
" &lt;&lt; n2 &lt;&lt; std::endl;<br>&nbsp;&nbsp;&nbsp; }</span><br><br>The=
 question is: What may happen at line<br><br><span style=3D"font-family: co=
urier new,monospace;">&nbsp;&nbsp;&nbsp; opt-&gt;ref =3D 1;</span><br><br>i=
n the former code or<br><br><span style=3D"font-family: courier new,monospa=
ce;">&nbsp;&nbsp;&nbsp; opt2.storage_.value_.ref =3D 1;</span><br><br>in th=
e latter (simplified) code?<br><br>According to N3485 - 3.8/7,<br><br>&nbsp=
;&nbsp;&nbsp; If, after the lifetime of an object has ended and before the<=
br>&nbsp;&nbsp;&nbsp; storage which the object occupied is reused or releas=
ed, a new<br>&nbsp;&nbsp;&nbsp; object is created at the storage location w=
hich the original<br>&nbsp;&nbsp;&nbsp; object occupied, a pointer that poi=
nted to the original object, a<br>&nbsp;&nbsp;&nbsp; reference that referre=
d to the original object, or the name of the<br>&nbsp;&nbsp;&nbsp; original=
 object will automatically refer to the new object and,<br>&nbsp;&nbsp;&nbs=
p; once the lifetime of the new object has started, can be used to<br>&nbsp=
;&nbsp;&nbsp; manipulate the new object, if:<br><br>&nbsp;&nbsp;&nbsp; [...=
]<br>&nbsp;&nbsp;&nbsp; =97 the type of the original object is not const-qu=
alified, and, if<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a class type, does not c=
ontain any non-static data member whose<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t=
ype is const-qualified or a reference type, and<br>&nbsp;&nbsp;&nbsp; [...]=
<br><br>In our case the cited condition is not satisfied, because A has a n=
on-static data member of a reference type =97 ref.<br><br>I presume that th=
e intention behind 3.8/7 was to allow optimizations described below:<br><br=
><span style=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; #in=
clude &lt;iostream&gt;<br><br>&nbsp;&nbsp;&nbsp; struct X<br>&nbsp;&nbsp;&n=
bsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int &amp;ref;<br>&nbsp=
;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; void f(X &amp;);<br><br>&nbsp;&n=
bsp;&nbsp; int main()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; int n =3D 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 X x{n};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f(x);<br>&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x.ref =3D 5;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp; std::cout &lt;&lt; n &lt;&lt; std::endl;<br>&nbsp;&nbsp;&nb=
sp; }<br></span><br>Here a compiler is allowed to assume that<br><br><span =
style=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; x.ref =3D =
5;</span><br><br>is equivalent to<br><br><span style=3D"font-family: courie=
r new,monospace;">&nbsp;&nbsp;&nbsp; n =3D 5;</span><br><br>and therefore<b=
r><br><span style=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp=
; std::cout &lt;&lt; n &lt;&lt; std::endl;</span><br><br>is equivalent to<b=
r><br><span style=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp=
; std::cout &lt;&lt; 5 &lt;&lt; std::endl;</span><br><br>regardless of the =
definition of f (which may be unknown for compiler). There is no legal way =
to modify reference <span style=3D"font-family: courier new,monospace;">x.r=
ef</span> after its initialization so that it would refer to a different lo=
cation. Even if we overwrite the storage of x by construction of a new obje=
ct of type X at address &amp;x (our mysterious f could do such thing), a co=
mpiler may assume that reference <span style=3D"font-family: courier new,mo=
nospace;">x.ref</span> is untouched.<br><br>The same applies to the origina=
l example with optional: it looks like a compiler is free to assume that <s=
pan style=3D"font-family: courier new,monospace;">opt-&gt;ref</span> or <sp=
an style=3D"font-family: courier new,monospace;">opt2.storage_.value_.ref</=
span> still refers to n1 (as if the accessed <span style=3D"font-family: co=
urier new,monospace;">ref</span> would be member of the old object) rather =
than n2 (to which new <span style=3D"font-family: courier new,monospace;">r=
ef</span> is supposed to refer). Such a behavior may be unexpected for some=
 programmers.<br><br>There are several ways to handle the issue. It's possi=
ble to:<br><br>1) reflect the limitations of the suggested implementation i=
n the specification of std::optional;<br><br>2) find a reliable portable (a=
nd potentially less effective) implementation without limitations regarding=
 to members of reference/const-qualified types;<br><br>3) acknowledge that =
an effective implementation of std::optional should rely on some compiler-s=
pecific behavior in order to avoid troubles with members of reference/const=
-qualified types;<br><br>4) make two templates: std::optional (which can us=
e std::aligned_storage) with normal support of assignment but without suppo=
rt of constexpr semantics, and std::literal_optional (which can use unions =
in order to implement constexpr semantics);<br><br>5) introduce special rul=
es for union members in order to make such tricks with unions well-defined;=
<br><br>6) reconsider the existing core rules in 3.8/7 more widely (not onl=
y with regard to unions).<br><br>There may be other options. Which directio=
n is the most preferable?<br>

<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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_41_24142763.1370004491584--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 31 May 2013 06:42:45 -0700 (PDT)
Raw View
------=_Part_331_31113905.1370007765370
Content-Type: text/plain; charset=ISO-8859-1


>
> Even if we overwrite the storage of x by construction of a new object of
> type X at address &x (our mysterious f could do such thing), a compiler may
> assume that reference x.ref is untouched.


If the Standard indeed says this, then that's hideously broken. A trivial
example not involving optional would be, say, the last element of a
std::vector. It's quite legal and normal for the user to overwrite
reference locations by destructing the original object and reconstructing a
new one in it's place. There's no way this optimization can present under
as-if or present sane results in many conditions.

--

---
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/?hl=en.



------=_Part_331_31113905.1370007765370
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<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;">Even if we overwrite the storage of x by const=
ruction of a new object of type X at address &amp;x (our mysterious f could=
 do such thing), a compiler may assume that reference&nbsp;<span style=3D"f=
ont-family: 'courier new', monospace;">x.ref</span>&nbsp;is untouched.</blo=
ckquote><div><br></div><div>If the Standard indeed says this, then that's h=
ideously broken. A trivial example not involving optional would be, say, th=
e last element of a std::vector. It's quite legal and normal for the user t=
o overwrite reference locations by destructing the original object and reco=
nstructing a new one in it's place. There's no way this optimization can pr=
esent under as-if or present sane results in many conditions.&nbsp;</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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_331_31113905.1370007765370--

.


Author: Nikolay Ivchenkov <mk.ivchenkov@gmail.com>
Date: Fri, 31 May 2013 08:17:18 -0700 (PDT)
Raw View
------=_Part_919_12643722.1370013438236
Content-Type: text/plain; charset=ISO-8859-1

On Friday, May 31, 2013 5:42:45 PM UTC+4, DeadMG wrote:
>
> A trivial example not involving optional would be, say, the last element
> of a std::vector. It's quite legal and normal for the user to overwrite
> reference locations by destructing the original object and reconstructing a
> new one in it's place.
>

We can do that:

    #include <iostream>
    #include <new>
    #include <vector>

    struct A
    {
        A(int &x) : ref(x) {}
        int &ref;
    };

    int main()
    {
        std::vector<A> v;
        int n1 = 0, n2 = 0;

        v.emplace_back(n1);
        A *p = &v.back();

        p->~A();
        A *q = new(p) A(n2);

        q->ref = 1; // q->ref shall refer to n2
        p->ref = 2; // p->ref may refer to n1
        std::cout << n1 << " " << n2 << std::endl;
    }

--

---
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/?hl=en.



------=_Part_919_12643722.1370013438236
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Friday, May 31, 2013 5:42:45 PM UTC+4, DeadMG wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div>A trivial example not involving optional woul=
d be, say, the last element of a std::vector. It's quite legal and normal f=
or the user to overwrite reference locations by destructing the original ob=
ject and reconstructing a new one in it's place.</div></blockquote><div><br=
>We can do that:<br><br><span style=3D"font-family: courier new,monospace;"=
>&nbsp;&nbsp;&nbsp; #include &lt;iostream&gt;<br>&nbsp;&nbsp;&nbsp; #includ=
e &lt;new&gt;<br>&nbsp;&nbsp;&nbsp; #include &lt;vector&gt;<br><br>&nbsp;&n=
bsp;&nbsp; struct A<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; A(int &amp;x) : ref(x) {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; int &amp;ref;<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp=
; int main()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; std::vector&lt;A&gt; v;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p; int n1 =3D 0, n2 =3D 0;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
; v.emplace_back(n1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A *p =
=3D &amp;v.back();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p-&gt;=
~A();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A *q =3D new(p) A(n2);<=
br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;ref =3D 1; // q-&gt=
;ref shall refer to n2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p-&gt;=
ref =3D 2; // p-&gt;ref may refer to n1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp; std::cout &lt;&lt; n1 &lt;&lt; " " &lt;&lt; n2 &lt;&lt; std::end=
l;<br>&nbsp;&nbsp;&nbsp; }</span><br></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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_919_12643722.1370013438236--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 31 May 2013 18:47:22 +0300
Raw View
--047d7bdca64ae290cc04de058755
Content-Type: text/plain; charset=ISO-8859-1

On 31 May 2013 18:17, Nikolay Ivchenkov <mk.ivchenkov@gmail.com> wrote:

> On Friday, May 31, 2013 5:42:45 PM UTC+4, DeadMG wrote:
>>
>> A trivial example not involving optional would be, say, the last element
>> of a std::vector. It's quite legal and normal for the user to overwrite
>> reference locations by destructing the original object and reconstructing a
>> new one in it's place.
>>
>
> We can do that:
>
>     #include <iostream>
>     #include <new>
>     #include <vector>
>
>     struct A
>     {
>
>         A(int &x) : ref(x) {}
>         int &ref;
>     };
>
>     int main()
>     {
>         std::vector<A> v;
>
>         int n1 = 0, n2 = 0;
>
>         v.emplace_back(n1);
>         A *p = &v.back();
>
>         p->~A();
>         A *q = new(p) A(n2);
>
>         q->ref = 1; // q->ref shall refer to n2
>         p->ref = 2; // p->ref may refer to n1
>
>         std::cout << n1 << " " << n2 << std::endl;
>     }
>
>
>
I suppose the vector internally has a pointer to the beginning of its
buffer, which is practically
a pointer to the first element, but since we reallocated a new element in
its place, the internal
pointer in the vector may or may not refer to the first element?

--

---
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/?hl=en.



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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 31 May 2013 18:17, Nikolay Ivchenkov <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:mk.ivchenkov@gmail.com" target=3D"_blank">mk.ivchenkov@gmail.c=
om</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On Friday, May 31, 2013 5:=
42:45 PM UTC+4, DeadMG wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>A trivial example not involving optional would be, say, the last eleme=
nt of a std::vector. It&#39;s quite legal and normal for the user to overwr=
ite reference locations by destructing the original object and reconstructi=
ng a new one in it&#39;s place.</div>
</blockquote></div><div><br>We can do that:<br><br><span style=3D"font-fami=
ly:courier new,monospace">=A0=A0=A0 #include &lt;iostream&gt;<br>=A0=A0=A0 =
#include &lt;new&gt;<br>=A0=A0=A0 #include &lt;vector&gt;<br><br>=A0=A0=A0 =
struct A<br>=A0=A0=A0 {<div class=3D"im">
<br>=A0=A0=A0=A0=A0=A0=A0 A(int &amp;x) : ref(x) {}<br>=A0=A0=A0=A0=A0=A0=
=A0 int &amp;ref;<br>=A0=A0=A0 };<br><br>=A0=A0=A0 int main()<br>=A0=A0=A0 =
{<br></div>=A0=A0=A0=A0=A0=A0=A0 std::vector&lt;A&gt; v;<div class=3D"im"><=
br>=A0=A0=A0=A0=A0=A0=A0 int n1 =3D 0, n2 =3D 0;<br><br></div>=A0=A0=A0=A0=
=A0=A0=A0 v.emplace_back(n1);<br>
=A0=A0=A0=A0=A0=A0=A0 A *p =3D &amp;v.back();<br><br>=A0=A0=A0=A0=A0=A0=A0 =
p-&gt;~A();<br>=A0=A0=A0=A0=A0=A0=A0 A *q =3D new(p) A(n2);<br><br>=A0=A0=
=A0=A0=A0=A0=A0 q-&gt;ref =3D 1; // q-&gt;ref shall refer to n2<br>=A0=A0=
=A0=A0=A0=A0=A0 p-&gt;ref =3D 2; // p-&gt;ref may refer to n1<div class=3D"=
im"><br>
=A0=A0=A0=A0=A0=A0=A0 std::cout &lt;&lt; n1 &lt;&lt; &quot; &quot; &lt;&lt;=
 n2 &lt;&lt; std::endl;<br>=A0=A0=A0 }</div></span><br><br></div></blockquo=
te><div><br></div><div>I suppose the vector internally has a pointer to the=
 beginning of its buffer, which is practically<br>
a pointer to the first element, but since we reallocated a new element in i=
ts place, the internal<br></div><div>pointer in the vector may or may not r=
efer to the first element? <br></div></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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

--047d7bdca64ae290cc04de058755--

.


Author: Nikolay Ivchenkov <mk.ivchenkov@gmail.com>
Date: Fri, 31 May 2013 09:42:29 -0700 (PDT)
Raw View
------=_Part_845_17522698.1370018549852
Content-Type: text/plain; charset=ISO-8859-1

On Friday, May 31, 2013 7:47:22 PM UTC+4, Ville Voutilainen wrote:
>
> I suppose the vector internally has a pointer to the beginning of its
> buffer, which is practically
> a pointer to the first element, but since we reallocated a new element in
> its place, the internal
> pointer in the vector may or may not refer to the first element?
>

I presume that implementation may use a pointer to void in order to safely
hold the address of the beginning of the allocated storage. Pointers to
void do not point to any objects and such aggressive optimizations should
not be applied to them.

BTW, issue 1280 describes similar case - see
http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/cwg_closed.html#1280
(with message 19275)

Unfortunately, issue 1280 was closed without any informative comments. Few
comments on 1280 can be found in

http://wiki.edg.com/twiki/bin/view/Wg21bloomington/CoreWorkingGroup

--

---
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/?hl=en.



------=_Part_845_17522698.1370018549852
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Friday, May 31, 2013 7:47:22 PM UTC+4, Ville Voutilainen wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I suppose the vector i=
nternally has a pointer to the beginning of its buffer, which is practicall=
y<br><div><div class=3D"gmail_quote"><div>
a pointer to the first element, but since we reallocated a new element in i=
ts place, the internal<br></div><div>pointer in the vector may or may not r=
efer to the first element?<br></div></div></div></div></blockquote><div><br=
>I presume that implementation may use a pointer to void in order to safely=
 hold the address of the beginning of the allocated storage. Pointers to vo=
id do not point to any objects and such aggressive optimizations should not=
 be applied to them.<br><br>BTW, issue 1280 describes similar case - see<br=
>http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/cwg_closed.html#1280=
<br>(with message 19275)<br><br>Unfortunately, issue 1280 was closed withou=
t any informative comments. Few comments on 1280 can be found in<br><pre>ht=
tp://wiki.edg.com/twiki/bin/view/Wg21bloomington/CoreWorkingGroup<br></pre>=
</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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_845_17522698.1370018549852--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Sun, 2 Jun 2013 23:54:58 -0700 (PDT)
Raw View
------=_Part_3431_7805328.1370242498634
Content-Type: text/plain; charset=ISO-8859-1



>
> There are several ways to handle the issue. It's possible to:
>
> 1) reflect the limitations of the suggested implementation in the
> specification of std::optional;
>
> 2) find a reliable portable (and potentially less effective)
> implementation without limitations regarding to members of
> reference/const-qualified types;
>
> 3) acknowledge that an effective implementation of std::optional should
> rely on some compiler-specific behavior in order to avoid troubles with
> members of reference/const-qualified types;
>
> 4) make two templates: std::optional (which can use std::aligned_storage)
> with normal support of assignment but without support of constexpr
> semantics, and std::literal_optional (which can use unions in order to
> implement constexpr semantics);
>
> 5) introduce special rules for union members in order to make such tricks
> with unions well-defined;
>
> 6) reconsider the existing core rules in 3.8/7 more widely (not only with
> regard to unions).
>
> There may be other options. Which direction is the most preferable?
>

The safest bet, I guess, will be to drop the requirement that std::optional
be a literal type.

Someone in this list (I cannot find the post anymore) also suggested
changing the rules for core constant expressions so that
std::aligned_storage is allowed in the implementation of literal
std::optional. Namely: using reinterpret_cast in core constant expressions.
Although I didn't give it enough thought to be confident it would fix the
problem.

Regards,
&rzej

--

---
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/?hl=en.



------=_Part_3431_7805328.1370242498634
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><br>There are several ways=
 to handle the issue. It's possible to:<br><br>1) reflect the limitations o=
f the suggested implementation in the specification of std::optional;<br><b=
r>2) find a reliable portable (and potentially less effective) implementati=
on without limitations regarding to members of reference/const-qualified ty=
pes;<br><br>3) acknowledge that an effective implementation of std::optiona=
l should rely on some compiler-specific behavior in order to avoid troubles=
 with members of reference/const-qualified types;<br><br>4) make two templa=
tes: std::optional (which can use std::aligned_storage) with normal support=
 of assignment but without support of constexpr semantics, and std::literal=
_optional (which can use unions in order to implement constexpr semantics);=
<br><br>5) introduce special rules for union members in order to make such =
tricks with unions well-defined;<br><br>6) reconsider the existing core rul=
es in 3.8/7 more widely (not only with regard to unions).<br><br>There may =
be other options. Which direction is the most preferable?<br></blockquote><=
div><br>The safest bet, I guess, will be to drop the requirement that std::=
optional be a literal type. <br><br>Someone
 in this list (I cannot find the post anymore) also suggested changing=20
the rules for core constant expressions so that std::aligned_storage is=20
allowed in the implementation of literal std::optional. Namely: using=20
reinterpret_cast in core constant expressions. Although I didn't give it
 enough thought to be confident it would fix the problem.<br><br>Regards,<b=
r>&amp;rzej <br></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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_3431_7805328.1370242498634--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 3 Jun 2013 10:02:06 +0300
Raw View
--047d7b6da692e1375604de3a8a60
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 3 June 2013 09:54, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wrote:

>
> Someone in this list (I cannot find the post anymore) also suggested
> changing the rules for core constant expressions so that
> std::aligned_storage is allowed in the implementation of literal
> std::optional. Namely: using reinterpret_cast in core constant expression=
s.
> Although I didn't give it enough thought to be confident it would fix the
> problem.
>
>
Off the top of my head, we could also entertain the idea of having a
compiler support library function that
is constexpr and converts aligned_storage to pointers of other type. Even
if that's a rather specific
"patch", I do think we want to avoid the can of worms that will open if
reinterpret_cast is allowed
in constant expressions.

Anyway, these things probably won't fix the issue with
destroying+placement-constructing.

--=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/?hl=3Den.



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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 3 June 2013 09:54, Andrzej Krzemie=F1ski <span dir=3D"ltr">&lt;<=
a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</=
a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br><div>Someone
 in this list (I cannot find the post anymore) also suggested changing=20
the rules for core constant expressions so that std::aligned_storage is=20
allowed in the implementation of literal std::optional. Namely: using=20
reinterpret_cast in core constant expressions. Although I didn&#39;t give i=
t
 enough thought to be confident it would fix the problem.<br><br></div></bl=
ockquote><div><br></div><div>Off the top of my head, we could also entertai=
n the idea of having a compiler support library function that<br></div>
<div>is constexpr and converts aligned_storage to pointers of other type. E=
ven if that&#39;s a rather specific<br></div><div>&quot;patch&quot;, I do t=
hink we want to avoid the can of worms that will open if reinterpret_cast i=
s allowed<br>
in constant expressions.<br></div><div><br></div><div>Anyway, these things =
probably won&#39;t fix the issue with destroying+placement-constructing.<br=
></div></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/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

--047d7b6da692e1375604de3a8a60--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 11 Sep 2013 07:05:08 -0700 (PDT)
Raw View
------=_Part_27_19161740.1378908308312
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu poniedzia=B3ek, 3 czerwca 2013 08:54:58 UTC+2 u=BFytkownik Andrzej=
=20
Krzemie=F1ski napisa=B3:
>
>
>
>> There are several ways to handle the issue. It's possible to:
>>
>> 1) reflect the limitations of the suggested implementation in the=20
>> specification of std::optional;
>>
>> 2) find a reliable portable (and potentially less effective)=20
>> implementation without limitations regarding to members of=20
>> reference/const-qualified types;
>>
>> 3) acknowledge that an effective implementation of std::optional should=
=20
>> rely on some compiler-specific behavior in order to avoid troubles with=
=20
>> members of reference/const-qualified types;
>>
>> 4) make two templates: std::optional (which can use std::aligned_storage=
)=20
>> with normal support of assignment but without support of constexpr=20
>> semantics, and std::literal_optional (which can use unions in order to=
=20
>> implement constexpr semantics);
>>
>> 5) introduce special rules for union members in order to make such trick=
s=20
>> with unions well-defined;
>>
>> 6) reconsider the existing core rules in 3.8/7 more widely (not only wit=
h=20
>> regard to unions).
>>
>> There may be other options. Which direction is the most preferable?
>>
>
> The safest bet, I guess, will be to drop the requirement that=20
> std::optional be a literal type.=20
>
> Someone in this list (I cannot find the post anymore) also suggested=20
> changing the rules for core constant expressions so that=20
> std::aligned_storage is allowed in the implementation of literal=20
> std::optional. Namely: using reinterpret_cast in core constant expression=
s.=20
> Although I didn't give it enough thought to be confident it would fix the=
=20
> problem.
>
> Regards,
> &rzej=20
>

Hi,
I remember that at some point someone mentioned that std::optional (with=20
its constexpr requirements) is not implementable in C++14. Is a defect=20
report for that reported in C++ Standard Core Language Active Issues? (I=20
couldn't find one)

Regards,
&rzej

--=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/.

------=_Part_27_19161740.1378908308312
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>W dniu poniedzia=B3ek, 3 czerwca 2013 08:54:58 UTC=
+2 u=BFytkownik Andrzej Krzemie=F1ski napisa=B3:<blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><br><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><br>There are=
 several ways to handle the issue. It's possible to:<br><br>1) reflect the =
limitations of the suggested implementation in the specification of std::op=
tional;<br><br>2) find a reliable portable (and potentially less effective)=
 implementation without limitations regarding to members of reference/const=
-qualified types;<br><br>3) acknowledge that an effective implementation of=
 std::optional should rely on some compiler-specific behavior in order to a=
void troubles with members of reference/const-qualified types;<br><br>4) ma=
ke two templates: std::optional (which can use std::aligned_storage) with n=
ormal support of assignment but without support of constexpr semantics, and=
 std::literal_optional (which can use unions in order to implement constexp=
r semantics);<br><br>5) introduce special rules for union members in order =
to make such tricks with unions well-defined;<br><br>6) reconsider the exis=
ting core rules in 3.8/7 more widely (not only with regard to unions).<br><=
br>There may be other options. Which direction is the most preferable?<br><=
/blockquote><div><br>The safest bet, I guess, will be to drop the requireme=
nt that std::optional be a literal type. <br><br>Someone
 in this list (I cannot find the post anymore) also suggested changing=20
the rules for core constant expressions so that std::aligned_storage is=20
allowed in the implementation of literal std::optional. Namely: using=20
reinterpret_cast in core constant expressions. Although I didn't give it
 enough thought to be confident it would fix the problem.<br><br>Regards,<b=
r>&amp;rzej <br></div></blockquote><div><br>Hi,<br>I remember that at some =
point someone mentioned that std::optional (with its constexpr requirements=
) is not implementable in C++14. Is a defect report for that reported in C+=
+ Standard Core Language Active Issues? (I couldn't find one)<br><br>Regard=
s,<br>&amp;rzej<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 />

------=_Part_27_19161740.1378908308312--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 11 Sep 2013 19:20:30 +0300
Raw View
--001a1133aa860962fc04e61e0079
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

On 11 September 2013 17:05, Andrzej Krzemie=F1ski <akrzemi1@gmail.com> wrot=
e:

>
>
> W dniu poniedzia=B3ek, 3 czerwca 2013 08:54:58 UTC+2 u=BFytkownik Andrzej
> Krzemie=F1ski napisa=B3:
>
>>
>>
>>> There are several ways to handle the issue. It's possible to:
>>>
>>> 1) reflect the limitations of the suggested implementation in the
>>> specification of std::optional;
>>>
>>> 2) find a reliable portable (and potentially less effective)
>>> implementation without limitations regarding to members of
>>> reference/const-qualified types;
>>>
>>> 3) acknowledge that an effective implementation of std::optional should
>>> rely on some compiler-specific behavior in order to avoid troubles with
>>> members of reference/const-qualified types;
>>>
>>> 4) make two templates: std::optional (which can use
>>> std::aligned_storage) with normal support of assignment but without sup=
port
>>> of constexpr semantics, and std::literal_optional (which can use unions=
 in
>>> order to implement constexpr semantics);
>>>
>>> 5) introduce special rules for union members in order to make such
>>> tricks with unions well-defined;
>>>
>>> 6) reconsider the existing core rules in 3.8/7 more widely (not only
>>> with regard to unions).
>>>
>>> There may be other options. Which direction is the most preferable?
>>>
>>
>> The safest bet, I guess, will be to drop the requirement that
>> std::optional be a literal type.
>>
>> Someone in this list (I cannot find the post anymore) also suggested
>> changing the rules for core constant expressions so that
>> std::aligned_storage is allowed in the implementation of literal
>> std::optional. Namely: using reinterpret_cast in core constant expressio=
ns.
>> Although I didn't give it enough thought to be confident it would fix th=
e
>> problem.
>>
>> Regards,
>> &rzej
>>
>
> Hi,
> I remember that at some point someone mentioned that std::optional (with
> its constexpr requirements) is not implementable in C++14. Is a defect
> report for that reported in C++ Standard Core Language Active Issues? (I
> couldn't find one)
>
>

I have filed an NB comment, FI 15, which covers that list of possible
solutions.
http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3733.pdf, page 12.

--=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/.

--001a1133aa860962fc04e61e0079
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 11 September 2013 17:05, Andrzej Krzemie=F1ski <span dir=3D"ltr"=
>&lt;<a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail=
..com</a>&gt;</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"><br><br>=
W dniu poniedzia=B3ek, 3 czerwca 2013 08:54:58 UTC+2 u=BFytkownik Andrzej K=
rzemie=F1ski napisa=B3:<div class=3D"im">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><br><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex">
<br>There are several ways to handle the issue. It&#39;s possible to:<br><b=
r>1) reflect the limitations of the suggested implementation in the specifi=
cation of std::optional;<br><br>2) find a reliable portable (and potentiall=
y less effective) implementation without limitations regarding to members o=
f reference/const-qualified types;<br>
<br>3) acknowledge that an effective implementation of std::optional should=
 rely on some compiler-specific behavior in order to avoid troubles with me=
mbers of reference/const-qualified types;<br><br>4) make two templates: std=
::optional (which can use std::aligned_storage) with normal support of assi=
gnment but without support of constexpr semantics, and std::literal_optiona=
l (which can use unions in order to implement constexpr semantics);<br>
<br>5) introduce special rules for union members in order to make such tric=
ks with unions well-defined;<br><br>6) reconsider the existing core rules i=
n 3.8/7 more widely (not only with regard to unions).<br><br>There may be o=
ther options. Which direction is the most preferable?<br>
</blockquote><div><br>The safest bet, I guess, will be to drop the requirem=
ent that std::optional be a literal type. <br><br>Someone
 in this list (I cannot find the post anymore) also suggested changing=20
the rules for core constant expressions so that std::aligned_storage is=20
allowed in the implementation of literal std::optional. Namely: using=20
reinterpret_cast in core constant expressions. Although I didn&#39;t give i=
t
 enough thought to be confident it would fix the problem.<br><br>Regards,<b=
r>&amp;rzej <br></div></blockquote></div><div><br>Hi,<br>I remember that at=
 some point someone mentioned that std::optional (with its constexpr requir=
ements) is not implementable in C++14. Is a defect report for that reported=
 in C++ Standard Core Language Active Issues? (I couldn&#39;t find one)<br>
<br></div></div></blockquote><div><br>=A0</div></div>I have filed an NB com=
ment, <span class=3D"">FI </span>15, which covers that list of possible sol=
utions.<br><a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n=
3733.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3733.pdf</a>=
, page 12.<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 />

--001a1133aa860962fc04e61e0079--

.


Author: Marshall Clow <mclow.lists@gmail.com>
Date: Wed, 11 Sep 2013 09:35:53 -0700
Raw View
On Sep 11, 2013, at 9:35 AM, Marshall Clow <mclow.lists@gmail.com> wrote:

> On Sep 11, 2013, at 7:05 AM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com> w=
rote:
>=20
>> Hi,
>> I remember that at some point someone mentioned that std::optional (with=
 its constexpr requirements) is not implementable in C++14. Is a defect rep=
ort for that reported in C++ Standard Core Language Active Issues? (I could=
n't find one)
>=20
> Hrm; I thought I reported one - but I don't see it either. Apparently I f=
orgot :-(
> My paper (n3749) describes the problem, and suggests a fix.
>=20
> An example of code that fails:
>=20
>  std::optional<int> o1{1};
>  static_assert ( o1 < 2, "1 < 2" );

D'oh!

 constexpr std::optional<int> o1{1};
 static_assert ( o1 < 2, "1 < 2" );


-- Marshall

Marshall Clow     Idio Software   <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is prom=
ptly moderated down to (-1, Flamebait).
        -- Yu Suzuki

--=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: Marshall Clow <mclow.lists@gmail.com>
Date: Wed, 11 Sep 2013 09:35:11 -0700
Raw View
On Sep 11, 2013, at 7:05 AM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> =
wrote:

> Hi,
> I remember that at some point someone mentioned that std::optional (with =
its constexpr requirements) is not implementable in C++14. Is a defect repo=
rt for that reported in C++ Standard Core Language Active Issues? (I couldn=
't find one)

Hrm; I thought I reported one - but I don't see it either. Apparently I for=
got :-(
My paper (n3749) describes the problem, and suggests a fix.

An example of code that fails:

 std::optional<int> o1{1};
 static_assert ( o1 < 2, "1 < 2" );

-- Marshall

Marshall Clow     Idio Software   <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is prom=
ptly moderated down to (-1, Flamebait).
        -- Yu Suzuki

--=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/.

.