Topic: Allow zero size arrays and let them occupy zero bytes.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Mon, 4 Jul 2016 08:15:15 -0700 (PDT)
Raw View
------=_Part_582_1701189990.1467645315293
Content-Type: multipart/alternative;
 boundary="----=_Part_583_1093741654.1467645315294"

------=_Part_583_1093741654.1467645315294
Content-Type: text/plain; charset=UTF-8

I have been following the recent thread about empty base optimization, or
rather, the lack of empty member optimization possibility. And today I
again fell in the 0 sized array trap in metaprogramming, noticing that it
creates quite a few problems requiring extra coding.

This idea struck me to solve both of these issues at once by a few small
changes:

1. Allow zero sized arrays in C++.

No code would break by just allowing something previously forbidden. The
problem with allowing this could have been to make up ones mind about what
size such an array should report.

2. Define that a zero size array occupies zero bytes.

As zero size arrays have never been allowed in C++ it can't be a breaking
change to define that the now allowed zero size arrays actually consume no
bytes regardless of the size of the element.

With these two rules in place it is possible to write this:

// Example container class.
template<typename T, typename A = std::allocator<T>> MyContainer {
public:
A& GetAllocator() { *m_allocator; } // Access the only element or if none
return some other address (next member) that the caller will not use anyway
as it points to 0 bytes of information.

private:
A m_allocator[std::is_empty<A> ? 0 : 1];
};

To be able to wrap the ugly ? operator and give the construct a
recognizable name some more provisions are needed, this is as if you wrap
the possibly empty array into a class that class is not a zero size array
and thus
by the current rules must occupy at least one byte.

3. Let is_empty return true if all members of a class are zero size arrays.

This is needed for rule 4 below and also seems reasonable.

4. Define that an is_empty class containing at least one zero sized array
occupies zero bytes when used as a member.

The drawback with this rule except that it complicates the standard
somewhat is that it could be tempting to add a `int dummy[0];` to for
instance std::allocator to mark it as zero-size while
some coder somewhere may (far fetched, but anyway) rely on the offset of an
allocator being different from the offset of adjacent members.

Now a general allow_empty wrapper can be written:

// Use zero sized array if T is empty to get rid of byte consumption.
template<typename T> struct allow_empty {
public:
operator T&() { return *m_data; } // use operator* instead of array
indexing to avoid compiler warnings or runtime checks.

private:
T m_data[std::is_empty<T> ? 0 : 1];
};


// Example.
template<typename T, typename A = std::allocator<T>> MyContainer {
public:
A& GetAllocator() { m_allocator; }
private:
std::allow_empty<A> m_allocator; // PROBLEM: While allow_empty is maybe
empty, special rule is required for m_allocator to use no space.
};



--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/51e6aec9-a745-4fd9-94f7-bdd78b5798ca%40isocpp.org.

------=_Part_583_1093741654.1467645315294
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I have been following the recent thread about empty b=
ase optimization, or rather, the lack of empty member optimization possibil=
ity. And today I again fell in the 0 sized array trap in metaprogramming, n=
oticing that it creates quite a few problems requiring extra coding.</div><=
div><br></div><div>This idea struck me to solve both of these issues at onc=
e by a few small changes:</div><div><br></div><div>1. Allow zero sized arra=
ys in C++.</div><div><br></div><div>No code would break by just allowing so=
mething previously forbidden. The problem with allowing this could have bee=
n to make up ones mind about what size such an array should report.</div><d=
iv><br></div><div>2. Define that a zero size array occupies zero bytes.</di=
v><div><br></div><div>As zero size arrays have never been allowed in C++ it=
 can&#39;t be a breaking change to define that the now allowed zero size ar=
rays actually consume no bytes regardless of the size of the element.</div>=
<div><br></div><div>With these two rules in place it is possible to write t=
his:</div><div><br></div><div><span class=3D"Apple-tab-span" style=3D"white=
-space:pre"> </span>// Example container class.</div><div><span class=3D"Ap=
ple-tab-span" style=3D"white-space:pre"> </span>template&lt;typename T, typ=
ename A =3D std::allocator&lt;T&gt;&gt; MyContainer {</div><div><span class=
=3D"Apple-tab-span" style=3D"white-space:pre"> </span>public:</div><div><sp=
an class=3D"Apple-tab-span" style=3D"white-space:pre">  </span>A&amp; GetAl=
locator() { *m_allocator; }<span class=3D"Apple-tab-span" style=3D"white-sp=
ace:pre"> </span>// Access the only element or if none return some other ad=
dress (next member) that the caller will not use anyway as it points to 0 b=
ytes of information.</div><div><br></div><div><span class=3D"Apple-tab-span=
" style=3D"white-space:pre"> </span>private:</div><div><span class=3D"Apple=
-tab-span" style=3D"white-space:pre">  </span>A m_allocator[std::is_empty&l=
t;A&gt; ? 0 : 1];</div><div><span class=3D"Apple-tab-span" style=3D"white-s=
pace:pre"> </span>};</div><div><br></div><div>To be able to wrap the ugly ?=
 operator and give the construct a recognizable name some more provisions a=
re needed, this is as if you wrap the possibly empty array into a class tha=
t class is not a zero size array and thus</div><div>by the current rules mu=
st occupy at least one byte.</div><div><br></div><div>3. Let is_empty retur=
n true if all members of a class are zero size arrays.</div><div><br></div>=
<div>This is needed for rule 4 below and also seems reasonable.</div><div><=
br></div><div>4. Define that an is_empty class containing at least one zero=
 sized array occupies zero bytes when used as a member.</div><div><br></div=
><div>The drawback with this rule except that it complicates the standard s=
omewhat is that it could be tempting to add a `int dummy[0];` to for instan=
ce std::allocator to mark it as zero-size while</div><div>some coder somewh=
ere may (far fetched, but anyway) rely on the offset of an allocator being =
different from the offset of adjacent members.</div><div><br></div><div>Now=
 a general allow_empty wrapper can be written:<br></div><div><br></div><div=
><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>// Use ze=
ro sized array if T is empty to get rid of byte consumption.</div><div><spa=
n class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>template&lt;ty=
pename T&gt; struct allow_empty {</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>public:</div><div><span class=3D"Apple-ta=
b-span" style=3D"white-space:pre">  </span>operator T&amp;() { return *m_da=
ta; }<span class=3D"Apple-tab-span" style=3D"white-space:pre">   </span>// =
use operator* instead of array indexing to avoid compiler warnings or runti=
me checks.</div><div><br></div><div><span class=3D"Apple-tab-span" style=3D=
"white-space:pre"> </span>private:</div><div><span class=3D"Apple-tab-span"=
 style=3D"white-space:pre">  </span>T m_data[std::is_empty&lt;T&gt; ? 0 : 1=
];</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </sp=
an>};</div><div><br></div><div><br></div><div><span class=3D"Apple-tab-span=
" style=3D"white-space:pre"> </span>// Example.</div><div><span class=3D"Ap=
ple-tab-span" style=3D"white-space:pre"> </span>template&lt;typename T, typ=
ename A =3D std::allocator&lt;T&gt;&gt; MyContainer {</div><div><span class=
=3D"Apple-tab-span" style=3D"white-space:pre"> </span>public:</div><div><sp=
an class=3D"Apple-tab-span" style=3D"white-space:pre">  </span>A&amp; GetAl=
locator() { m_allocator; }<span class=3D"Apple-tab-span" style=3D"white-spa=
ce:pre"> </span></div><div><span class=3D"Apple-tab-span" style=3D"white-sp=
ace:pre"> </span>private:</div><div><span class=3D"Apple-tab-span" style=3D=
"white-space:pre">  </span>std::allow_empty&lt;A&gt; m_allocator;<span clas=
s=3D"Apple-tab-span" style=3D"white-space:pre">  </span>// PROBLEM: While a=
llow_empty is maybe empty, special rule is required for m_allocator to use =
no space.</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre=
"> </span>};</div><div><br></div><div><br></div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/51e6aec9-a745-4fd9-94f7-bdd78b5798ca%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/51e6aec9-a745-4fd9-94f7-bdd78b5798ca=
%40isocpp.org</a>.<br />

------=_Part_583_1093741654.1467645315294--

------=_Part_582_1701189990.1467645315293--

.


Author: "smilingthax via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 4 Jul 2016 09:26:46 -0700 (PDT)
Raw View
------=_Part_498_1954080901.1467649606149
Content-Type: multipart/alternative;
 boundary="----=_Part_499_1572309010.1467649606149"

------=_Part_499_1572309010.1467649606149
Content-Type: text/plain; charset=UTF-8

On Monday, July 4, 2016 at 5:15:15 PM UTC+2, Bengt Gustafsson wrote:
>
> I have been following the recent thread about empty base optimization, or
> rather, the lack of empty member optimization possibility. And today I
> again fell in the 0 sized array trap in metaprogramming, noticing that it
> creates quite a few problems requiring extra coding.
>
> This idea struck me to solve both of these issues at once by a few small
> changes:
>
> 1. Allow zero sized arrays in C++.
>
> No code would break by just allowing something previously forbidden. The
> problem with allowing this could have been to make up ones mind about what
> size such an array should report.
>

One of the (current) SFINAE rules is that attempting to create an array of
size zero causes the template instantiation to fail.
This forces the compiler to consider other possible candidates.
Allowing zero sized arrays would cause the instantiation to succeed, which
will obviously change the behaviour of existing programs.

  Tobias



--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2ac902ec-4360-4bcd-8778-d54e39c2d914%40isocpp.org.

------=_Part_499_1572309010.1467649606149
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, July 4, 2016 at 5:15:15 PM UTC+2, Bengt Gustafs=
son wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v>I have been following the recent thread about empty base optimization, or=
 rather, the lack of empty member optimization possibility. And today I aga=
in fell in the 0 sized array trap in metaprogramming, noticing that it crea=
tes quite a few problems requiring extra coding.</div><div><br></div><div>T=
his idea struck me to solve both of these issues at once by a few small cha=
nges:</div><div><br></div><div>1. Allow zero sized arrays in C++.</div><div=
><br></div><div>No code would break by just allowing something previously f=
orbidden. The problem with allowing this could have been to make up ones mi=
nd about what size such an array should report.</div></div></blockquote><di=
v><br></div><div>One of the (current) SFINAE rules is that attempting to cr=
eate an array of size zero causes the template instantiation to fail.<br>Th=
is forces the compiler to consider other possible candidates.<br>Allowing z=
ero sized arrays would cause the instantiation to succeed, which will obvio=
usly change the behaviour of existing programs.<br><br>=C2=A0 Tobias<br><br=
></div><div>=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2ac902ec-4360-4bcd-8778-d54e39c2d914%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2ac902ec-4360-4bcd-8778-d54e39c2d914=
%40isocpp.org</a>.<br />

------=_Part_499_1572309010.1467649606149--

------=_Part_498_1954080901.1467649606149--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 4 Jul 2016 09:30:23 -0700 (PDT)
Raw View
------=_Part_192_1739594926.1467649824042
Content-Type: multipart/alternative;
 boundary="----=_Part_193_1352269455.1467649824043"

------=_Part_193_1352269455.1467649824043
Content-Type: text/plain; charset=UTF-8



On Monday, July 4, 2016 at 11:15:15 AM UTC-4, Bengt Gustafsson wrote:
>
> I have been following the recent thread about empty base optimization, or
> rather, the lack of empty member optimization possibility. And today I
> again fell in the 0 sized array trap in metaprogramming, noticing that it
> creates quite a few problems requiring extra coding.
>
> This idea struck me to solve both of these issues at once by a few small
> changes:
>
> 1. Allow zero sized arrays in C++.
>
> No code would break by just allowing something previously forbidden. The
> problem with allowing this could have been to make up ones mind about what
> size such an array should report.
>

Allow them to do... what?


> 2. Define that a zero size array occupies zero bytes.
>

The C++ object model requires that objects take up storage. If you have an
array that has no objects in it, then you clearly cannot use objects that
don't exist. So having an array of 0 objects means that you can't do
anything with `a[0]`.

Merely permitting the syntax doesn't work. You have to actually define what
that *means*. Whether it's a zero-sized array or an object that takes no
storage or whatever, you still need to do the hard work of deciding what
that actually means.

And for a zero-sized array, you also have to decide what it means for the
array to decay to a pointer.

How we declare that a variable takes up no storage is not the hard part of
having stateless members. Whether it's a magic standard library type, a
zero-size array, or a new keyword, that's the easy part. The hard part is
deciding what they mean, how pointers to them work, how they get copied,
etc.

And you haven't really done any of that work.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e5840a9e-4d1d-43fe-b2b0-fbd87557197f%40isocpp.org.

------=_Part_193_1352269455.1467649824043
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, July 4, 2016 at 11:15:15 AM UTC-4, Beng=
t Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div>I have been following the recent thread about empty base optimiz=
ation, or rather, the lack of empty member optimization possibility. And to=
day I again fell in the 0 sized array trap in metaprogramming, noticing tha=
t it creates quite a few problems requiring extra coding.</div><div><br></d=
iv><div>This idea struck me to solve both of these issues at once by a few =
small changes:</div><div><br></div><div>1. Allow zero sized arrays in C++.<=
/div><div><br></div><div>No code would break by just allowing something pre=
viously forbidden. The problem with allowing this could have been to make u=
p ones mind about what size such an array should report.</div></div></block=
quote><div><br>Allow them to do... what?<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>2. Define that=
 a zero size array occupies zero bytes.</div></div></blockquote><div><br>Th=
e C++ object model requires that objects take up storage. If you have=20
an array that has no objects in it, then you clearly cannot use objects=20
that don&#39;t exist. So having an array of 0 objects means that you can&#3=
9;t=20
do anything with `a[0]`.<br><br>Merely permitting the syntax doesn&#39;t wo=
rk. You have to actually define what that <i>means</i>.
 Whether it&#39;s a zero-sized array or an object that takes no storage or=
=20
whatever, you still need to do the hard work of deciding what that=20
actually means.<br><br>And for a zero-sized array, you also have to decide =
what it means for the array to decay to a pointer.<br><br>How we declare th=
at a variable takes up no storage is not the hard part of having stateless =
members. Whether it&#39;s a magic standard library type, a zero-size array,=
 or a new keyword, that&#39;s the easy part. The hard part is deciding what=
 they mean, how pointers to them work, how they get copied, etc.<br><br>And=
 you haven&#39;t really done any of that work.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e5840a9e-4d1d-43fe-b2b0-fbd87557197f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e5840a9e-4d1d-43fe-b2b0-fbd87557197f=
%40isocpp.org</a>.<br />

------=_Part_193_1352269455.1467649824043--

------=_Part_192_1739594926.1467649824042--

.


Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Mon, 4 Jul 2016 12:34:06 -0700 (PDT)
Raw View
------=_Part_214_1681476997.1467660846419
Content-Type: multipart/alternative;
 boundary="----=_Part_215_149930233.1467660846419"

------=_Part_215_149930233.1467660846419
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



=E5=9C=A8 2016=E5=B9=B47=E6=9C=884=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=80 UTC+=
8=E4=B8=8B=E5=8D=8811:15:15=EF=BC=8CBengt Gustafsson=E5=86=99=E9=81=93=EF=
=BC=9A
>
> I have been following the recent thread about empty base optimization, or=
=20
> rather, the lack of empty member optimization possibility. And today I=20
> again fell in the 0 sized array trap in metaprogramming, noticing that it=
=20
> creates quite a few problems requiring extra coding.
>
> This idea struck me to solve both of these issues at once by a few small=
=20
> changes:
>
> 1. Allow zero sized arrays in C++.
>
> No code would break by just allowing something previously forbidden. The=
=20
> problem with allowing this could have been to make up ones mind about wha=
t=20
> size such an array should report.
>
> As said, SFINAE BOOMs.
=20

> 2. Define that a zero size array occupies zero bytes.
>
> As zero size arrays have never been allowed in C++ it can't be a breaking=
=20
> change to define that the now allowed zero size arrays actually consume n=
o=20
> bytes regardless of the size of the element.
>
> With these two rules in place it is possible to write this:
>
> // Example container class.
> template<typename T, typename A =3D std::allocator<T>> MyContainer {
> public:
> A& GetAllocator() { *m_allocator; } // Access the only element or if none=
=20
> return some other address (next member) that the caller will not use anyw=
ay=20
> as it points to 0 bytes of information.
>
> private:
> A m_allocator[std::is_empty<A> ? 0 : 1];
> };
>
> To be able to wrap the ugly ? operator and give the construct a=20
> recognizable name some more provisions are needed, this is as if you wrap=
=20
> the possibly empty array into a class that class is not a zero size array=
=20
> and thus
> by the current rules must occupy at least one byte.
>
> I don't think it is possible to change the meaning of object=20
types/objects/object model without serious problems and redesigning of the=
=20
majority part of the language. The only clean (?) way is to propose a new=
=20
kind of entity in parallel to existed void types, object types, function=20
types and reference types and then you can require it shall always take=20
zero storage.
=20

> 3. Let is_empty return true if all members of a class are zero size array=
s.
>
> This is needed for rule 4 below and also seems reasonable.
>
> 4. Define that an is_empty class containing at least one zero sized array=
=20
> occupies zero bytes when used as a member.
>
> The drawback with this rule except that it complicates the standard=20
> somewhat is that it could be tempting to add a `int dummy[0];` to for=20
> instance std::allocator to mark it as zero-size while
> some coder somewhere may (far fetched, but anyway) rely on the offset of=
=20
> an allocator being different from the offset of adjacent members.
>
> Now a general allow_empty wrapper can be written:
>
> // Use zero sized array if T is empty to get rid of byte consumption.
> template<typename T> struct allow_empty {
> public:
> operator T&() { return *m_data; } // use operator* instead of array=20
> indexing to avoid compiler warnings or runtime checks.
>
> private:
> T m_data[std::is_empty<T> ? 0 : 1];
> };
>
>
> // Example.
> template<typename T, typename A =3D std::allocator<T>> MyContainer {
> public:
> A& GetAllocator() { m_allocator; }=20
> private:
> std::allow_empty<A> m_allocator; // PROBLEM: While allow_empty is maybe=
=20
> empty, special rule is required for m_allocator to use no space.
> };
>
>
>
>

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3506e940-4145-49f1-8849-dae44cd195b8%40isocpp.or=
g.

------=_Part_215_149930233.1467660846419
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B47=E6=9C=884=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=80 UTC+8=E4=B8=8B=E5=8D=8811:15:15=EF=BC=8CBengt Gustafs=
son=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div>I have been following the recent thread about empty b=
ase optimization, or rather, the lack of empty member optimization possibil=
ity. And today I again fell in the 0 sized array trap in metaprogramming, n=
oticing that it creates quite a few problems requiring extra coding.</div><=
div><br></div><div>This idea struck me to solve both of these issues at onc=
e by a few small changes:</div><div><br></div><div>1. Allow zero sized arra=
ys in C++.</div><div><br></div><div>No code would break by just allowing so=
mething previously forbidden. The problem with allowing this could have bee=
n to make up ones mind about what size such an array should report.</div><d=
iv><br></div></div></blockquote><div>As said, SFINAE BOOMs.<br>=C2=A0<br></=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></di=
v><div>2. Define that a zero size array occupies zero bytes.</div><div><br>=
</div><div>As zero size arrays have never been allowed in C++ it can&#39;t =
be a breaking change to define that the now allowed zero size arrays actual=
ly consume no bytes regardless of the size of the element.</div><div><br></=
div><div>With these two rules in place it is possible to write this:</div><=
div><br></div><div><span style=3D"white-space:pre"> </span>// Example conta=
iner class.</div><div><span style=3D"white-space:pre"> </span>template&lt;t=
ypename T, typename A =3D std::allocator&lt;T&gt;&gt; MyContainer {</div><d=
iv><span style=3D"white-space:pre"> </span>public:</div><div><span style=3D=
"white-space:pre">  </span>A&amp; GetAllocator() { *m_allocator; }<span sty=
le=3D"white-space:pre"> </span>// Access the only element or if none return=
 some other address (next member) that the caller will not use anyway as it=
 points to 0 bytes of information.</div><div><br></div><div><span style=3D"=
white-space:pre"> </span>private:</div><div><span style=3D"white-space:pre"=
>  </span>A m_allocator[std::is_empty&lt;A&gt; ? 0 : 1];</div><div><span st=
yle=3D"white-space:pre"> </span>};</div><div><br></div><div>To be able to w=
rap the ugly ? operator and give the construct a recognizable name some mor=
e provisions are needed, this is as if you wrap the possibly empty array in=
to a class that class is not a zero size array and thus</div><div>by the cu=
rrent rules must occupy at least one byte.</div><div><br></div></div></bloc=
kquote><div>I don&#39;t think it is possible to change the meaning of objec=
t types/objects/object model without serious problems and redesigning of th=
e majority part of the language. The only clean (?) way is to propose a new=
 kind of entity in parallel to existed void types, object types, function t=
ypes and reference types and then you can require it shall always take zero=
 storage.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div></div><div>3. Let is_empty return true if all members =
of a class are zero size arrays.</div><div><br></div><div>This is needed fo=
r rule 4 below and also seems reasonable.</div><div><br></div><div>4. Defin=
e that an is_empty class containing at least one zero sized array occupies =
zero bytes when used as a member.</div><div><br></div><div>The drawback wit=
h this rule except that it complicates the standard somewhat is that it cou=
ld be tempting to add a `int dummy[0];` to for instance std::allocator to m=
ark it as zero-size while</div><div>some coder somewhere may (far fetched, =
but anyway) rely on the offset of an allocator being different from the off=
set of adjacent members.</div><div><br></div><div>Now a general allow_empty=
 wrapper can be written:<br></div><div><br></div><div><span style=3D"white-=
space:pre"> </span>// Use zero sized array if T is empty to get rid of byte=
 consumption.</div><div><span style=3D"white-space:pre"> </span>template&lt=
;typename T&gt; struct allow_empty {</div><div><span style=3D"white-space:p=
re"> </span>public:</div><div><span style=3D"white-space:pre">  </span>oper=
ator T&amp;() { return *m_data; }<span style=3D"white-space:pre">   </span>=
// use operator* instead of array indexing to avoid compiler warnings or ru=
ntime checks.</div><div><br></div><div><span style=3D"white-space:pre"> </s=
pan>private:</div><div><span style=3D"white-space:pre">  </span>T m_data[st=
d::is_empty&lt;T&gt; ? 0 : 1];</div><div><span style=3D"white-space:pre"> <=
/span>};</div><div><br></div><div><br></div><div><span style=3D"white-space=
:pre"> </span>// Example.</div><div><span style=3D"white-space:pre"> </span=
>template&lt;typename T, typename A =3D std::allocator&lt;T&gt;&gt; MyConta=
iner {</div><div><span style=3D"white-space:pre"> </span>public:</div><div>=
<span style=3D"white-space:pre">  </span>A&amp; GetAllocator() { m_allocato=
r; }<span style=3D"white-space:pre"> </span></div><div><span style=3D"white=
-space:pre"> </span>private:</div><div><span style=3D"white-space:pre">  </=
span>std::allow_empty&lt;A&gt; m_allocator;<span style=3D"white-space:pre">=
  </span>// PROBLEM: While allow_empty is maybe empty, special rule is requ=
ired for m_allocator to use no space.</div><div><span style=3D"white-space:=
pre"> </span>};</div><div><br></div><div><br></div><div><br></div></div></b=
lockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3506e940-4145-49f1-8849-dae44cd195b8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3506e940-4145-49f1-8849-dae44cd195b8=
%40isocpp.org</a>.<br />

------=_Part_215_149930233.1467660846419--

------=_Part_214_1681476997.1467660846419--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 04 Jul 2016 13:12:33 -0700
Raw View
On segunda-feira, 4 de julho de 2016 08:15:15 PDT Bengt Gustafsson wrote:
> No code would break by just allowing something previously forbidden.

[not specific to the case you're proposed, but in general terms]

Except code that used the fact that it was forbidden to cause a compilation
error.

A.k.a. "poor man's static_assert"

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2340013.jDN0abQg6Y%40tjmaciei-mobl1.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 6 Jul 2016 01:59:55 -0700 (PDT)
Raw View
------=_Part_2859_1095922345.1467795595869
Content-Type: multipart/alternative;
 boundary="----=_Part_2860_1351624783.1467795595869"

------=_Part_2860_1351624783.1467795595869
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I see no problem with defining the meanings you are after here. Use logic.=
=20
See also below.

Den m=C3=A5ndag 4 juli 2016 kl. 18:30:24 UTC+2 skrev Nicol Bolas:
>
>
>
> On Monday, July 4, 2016 at 11:15:15 AM UTC-4, Bengt Gustafsson wrote:
>>
>> I have been following the recent thread about empty base optimization, o=
r=20
>> rather, the lack of empty member optimization possibility. And today I=
=20
>> again fell in the 0 sized array trap in metaprogramming, noticing that i=
t=20
>> creates quite a few problems requiring extra coding.
>>
>> This idea struck me to solve both of these issues at once by a few small=
=20
>> changes:
>>
>> 1. Allow zero sized arrays in C++.
>>
>> No code would break by just allowing something previously forbidden. The=
=20
>> problem with allowing this could have been to make up ones mind about wh=
at=20
>> size such an array should report.
>>
>
> Allow them to do... what?
>
Be declared. Have their address taken. Said address being being that of the=
=20
first addressable byte after the previous variable in the scope. From this=
=20
follows that begin() and end() on zero sized arrays both return this=20
address, so that range based for loops 0 times.
=20

> =20
>
>> 2. Define that a zero size array occupies zero bytes.
>>
>
> The C++ object model requires that objects take up storage. If you have a=
n=20
> array that has no objects in it, then you clearly cannot use objects that=
=20
> don't exist. So having an array of 0 objects means that you can't do=20
> anything with `a[0]`.
>
Of course not, just as with an array sized 1 you can't do anything with=20
a[1], because there is nothing there.

Of course any writing in the standard document mentioning that all C++=20
objects must take up storage must be amended with a clause that excepts=20
zero sized arrays.
=20

>
> Merely permitting the syntax doesn't work. You have to actually define=20
> what that *means*. Whether it's a zero-sized array or an object that=20
> takes no storage or whatever, you still need to do the hard work of=20
> deciding what that actually means.
>
I think all that is needed is stated above.=20

>
> And for a zero-sized array, you also have to decide what it means for the=
=20
> array to decay to a pointer.
>
It decays to its address as defined above. At this address there is no=20
valid object, just as there isnt when you do &a[1] for a 1-long array=20
today. I fail to see a problem here.=20

>
> How we declare that a variable takes up no storage is not the hard part o=
f=20
> having stateless members. Whether it's a magic standard library type, a=
=20
> zero-size array, or a new keyword, that's the easy part. The hard part is=
=20
> deciding what they mean, how pointers to them work, how they get copied,=
=20
> etc.
>
An advantage of using the zero-sized array idiom is that the question of=20
"how do I iterate over an array of zero sized objects" does not come up as=
=20
a separate issue.=20

>
> And you haven't really done any of that work.
>
Now I have.

=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/a71feb51-eacc-4a7f-b4dd-246be6b104f9%40isocpp.or=
g.

------=_Part_2860_1351624783.1467795595869
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I see no problem with defining the meanings you are after =
here. Use logic. See also below.<br><br>Den m=C3=A5ndag 4 juli 2016 kl. 18:=
30:24 UTC+2 skrev Nicol Bolas:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><br><br>On Monday, July 4, 2016 at 11:15:15 AM UTC-4, Beng=
t Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div>I have been following the recent thread about empty base optimization=
, or rather, the lack of empty member optimization possibility. And today I=
 again fell in the 0 sized array trap in metaprogramming, noticing that it =
creates quite a few problems requiring extra coding.</div><div><br></div><d=
iv>This idea struck me to solve both of these issues at once by a few small=
 changes:</div><div><br></div><div>1. Allow zero sized arrays in C++.</div>=
<div><br></div><div>No code would break by just allowing something previous=
ly forbidden. The problem with allowing this could have been to make up one=
s mind about what size such an array should report.</div></div></blockquote=
><div><br>Allow them to do... what?<br></div></div></blockquote><div>Be dec=
lared. Have their address taken. Said address being being that of the first=
 addressable byte after the previous variable in the scope. From this follo=
ws that begin() and end() on zero sized arrays both return this address, so=
 that range based for loops 0 times.</div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>2. Define that=
 a zero size array occupies zero bytes.</div></div></blockquote><div><br>Th=
e C++ object model requires that objects take up storage. If you have=20
an array that has no objects in it, then you clearly cannot use objects=20
that don&#39;t exist. So having an array of 0 objects means that you can&#3=
9;t=20
do anything with `a[0]`.<br></div></div></blockquote><div>Of course not, ju=
st as with an array sized 1 you can&#39;t do anything with a[1], because th=
ere is nothing there.</div><div><br></div><div>Of course any writing in the=
 standard document mentioning that all C++ objects must take up storage mus=
t be amended with a clause that excepts zero sized arrays.</div><div>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><b=
r>Merely permitting the syntax doesn&#39;t work. You have to actually defin=
e what that <i>means</i>.
 Whether it&#39;s a zero-sized array or an object that takes no storage or=
=20
whatever, you still need to do the hard work of deciding what that=20
actually means.<br></div></div></blockquote><div>I think all that is needed=
 is stated above.=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div><br>And for a zero-sized array, you also have to decid=
e what it means for the array to decay to a pointer.<br></div></div></block=
quote><div>It decays to its address as defined above. At this address there=
 is no valid object, just as there isnt when you do &amp;a[1] for a 1-long =
array today. I fail to see a problem here.=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>How we declare that a var=
iable takes up no storage is not the hard part of having stateless members.=
 Whether it&#39;s a magic standard library type, a zero-size array, or a ne=
w keyword, that&#39;s the easy part. The hard part is deciding what they me=
an, how pointers to them work, how they get copied, etc.<br></div></div></b=
lockquote><div>An advantage of using the zero-sized array idiom is that the=
 question of &quot;how do I iterate over an array of zero sized objects&quo=
t; does not come up as a separate issue.=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div><br>And you haven&#39;t really =
done any of that work.<br></div></div></blockquote><div>Now I have.</div><d=
iv><br></div><div>=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a71feb51-eacc-4a7f-b4dd-246be6b104f9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a71feb51-eacc-4a7f-b4dd-246be6b104f9=
%40isocpp.org</a>.<br />

------=_Part_2860_1351624783.1467795595869--

------=_Part_2859_1095922345.1467795595869--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 6 Jul 2016 02:00:22 -0700 (PDT)
Raw View
------=_Part_7620_674377918.1467795622375
Content-Type: multipart/alternative;
 boundary="----=_Part_7621_1846274363.1467795622375"

------=_Part_7621_1846274363.1467795622375
Content-Type: text/plain; charset=UTF-8


>
> One of the (current) SFINAE rules is that attempting to create an array of
> size zero causes the template instantiation to fail.
> This forces the compiler to consider other possible candidates.
> Allowing zero sized arrays would cause the instantiation to succeed, which
> will obviously change the behaviour of existing programs.
>
>   Tobias
>
>
> This is unfortunate. But can you come up with a case where such SFINAE can
actually be used? To me it seems that to use this rule you would have to
create a zero sized array first and then try to call a function templated
on the array size with it. But then you get a hard error
for trying to make the array (under current rules)! Maybe there are more
complicated cases but I think there has to be at least one that is possible
to use today, or this SFINAE rule is superflous. Given actual uses of this
rule an assessment can be made whether breaking such code can be accepted.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1a770421-ef9d-49e6-b2c8-0aacd9302d92%40isocpp.org.

------=_Part_7621_1846274363.1467795622375
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div>One of the (current) SFINAE rules is that attempting to create an =
array of size zero causes the template instantiation to fail.<br></div><div=
>This forces the compiler to consider other possible candidates.<br>Allowin=
g zero sized arrays would cause the instantiation to succeed, which will ob=
viously change the behaviour of existing programs.<br><br>=C2=A0 Tobias<br>=
<br></div><div><br></div></div></blockquote><div>This is unfortunate. But c=
an you come up with a case where such SFINAE can actually be used? To me it=
 seems that to use this rule you would have to create a zero sized array fi=
rst and then try to call a function templated on the array size with it. Bu=
t then you get a hard error</div><div>for trying to make the array (under c=
urrent rules)! Maybe there are more complicated cases but I think there has=
 to be at least one that is possible to use today, or this SFINAE rule is s=
uperflous. Given actual uses of this rule an assessment can be made whether=
 breaking such code can be accepted.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1a770421-ef9d-49e6-b2c8-0aacd9302d92%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1a770421-ef9d-49e6-b2c8-0aacd9302d92=
%40isocpp.org</a>.<br />

------=_Part_7621_1846274363.1467795622375--

------=_Part_7620_674377918.1467795622375--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 6 Jul 2016 02:05:10 -0700 (PDT)
Raw View
------=_Part_153_386133720.1467795910950
Content-Type: multipart/alternative;
 boundary="----=_Part_154_364156037.1467795910950"

------=_Part_154_364156037.1467795910950
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

This is the most serious problem among the responses here, I think. Are=20
there known code bases that uses this? Was it tought as a "good way" to do=
=20
static asserting in the old days?

Not generating error messages for newly created bugs which can then require=
=20
serious debugging is not good. But if such code bases are under serious=20
development, should they not start using static_assert soon? Can anyone=20
come up with  a way to detect such uses of potentially zero sized arrays (I=
=20
think that would be hard, unfortunately).




Den m=C3=A5ndag 4 juli 2016 kl. 22:12:37 UTC+2 skrev Thiago Macieira:
>
> On segunda-feira, 4 de julho de 2016 08:15:15 PDT Bengt Gustafsson wrote:=
=20
> > No code would break by just allowing something previously forbidden.=20
>
> [not specific to the case you're proposed, but in general terms]=20
>
> Except code that used the fact that it was forbidden to cause a=20
> compilation=20
> error.=20
>
> A.k.a. "poor man's static_assert"=20
>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>    Software Architect - Intel Open Source Technology Center=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f9c726a2-047b-4dfc-ba10-59ef2ce7c6f1%40isocpp.or=
g.

------=_Part_154_364156037.1467795910950
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is the most serious problem among the responses here,=
 I think. Are there known code bases that uses this? Was it tought as a &qu=
ot;good way&quot; to do static asserting in the old days?<div><br></div><di=
v>Not generating error messages for newly created bugs which can then requi=
re serious debugging is not good. But if such code bases are under serious =
development, should they not start using static_assert soon? Can anyone com=
e up with =C2=A0a way to detect such uses of potentially zero sized arrays =
(I think that would be hard, unfortunately).</div><div><br></div><div><br><=
/div><div><br><br>Den m=C3=A5ndag 4 juli 2016 kl. 22:12:37 UTC+2 skrev Thia=
go Macieira:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On segunda-feira, =
4 de julho de 2016 08:15:15 PDT Bengt Gustafsson wrote:
<br>&gt; No code would break by just allowing something previously forbidde=
n.
<br>
<br>[not specific to the case you&#39;re proposed, but in general terms]=20
<br>
<br>Except code that used the fact that it was forbidden to cause a compila=
tion=20
<br>error.
<br>
<br>A.k.a. &quot;poor man&#39;s static_assert&quot;
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f9c726a2-047b-4dfc-ba10-59ef2ce7c6f1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f9c726a2-047b-4dfc-ba10-59ef2ce7c6f1=
%40isocpp.org</a>.<br />

------=_Part_154_364156037.1467795910950--

------=_Part_153_386133720.1467795910950--

.


Author: "smilingthax via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 6 Jul 2016 02:10:56 -0700 (PDT)
Raw View
------=_Part_459_1680366961.1467796256104
Content-Type: multipart/alternative;
 boundary="----=_Part_460_2054117735.1467796256105"

------=_Part_460_2054117735.1467796256105
Content-Type: text/plain; charset=UTF-8

On Wednesday, July 6, 2016 at 11:00:22 AM UTC+2, Bengt Gustafsson wrote:
>
> One of the (current) SFINAE rules is that attempting to create an array of
>> size zero causes the template instantiation to fail.
>> This forces the compiler to consider other possible candidates.
>> Allowing zero sized arrays would cause the instantiation to succeed,
>> which will obviously change the behaviour of existing programs.
>>
>>   Tobias
>>
>>
>> This is unfortunate. But can you come up with a case where such SFINAE
> can actually be used? To me it seems that to use this rule you would have
> to create a zero sized array first and then try to call a function
> templated on the array size with it. But then you get a hard error
> for trying to make the array (under current rules)! Maybe there are more
> complicated cases but I think there has to be at least one that is possible
> to use today, or this SFINAE rule is superflous. Given actual uses of this
> rule an assessment can be made whether breaking such code can be accepted.
>

One of the ways the SFINAE-rule is actually used:
  void foo(char (*)[...evaluates to 0 or >0...] =0)
  void foo(...)   // other overloads

which is (currently) equivalent to (e.g.)

  std::disable_if<...evaluates to false/true...>::type foo();
  // other overloads

but would not, if zero-sized arrays are allowed (developers would have to
replace "[value]" with "[2*(value)-1]" to get a negative-sized array for
"false" to still fail SFINAE).

  Tobias


--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d5fea17c-34cc-41d4-9921-33e1dca3cc60%40isocpp.org.

------=_Part_460_2054117735.1467796256105
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, July 6, 2016 at 11:00:22 AM UTC+2, Bengt Gus=
tafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>One of the (=
current) SFINAE rules is that attempting to create an array of size zero ca=
uses the template instantiation to fail.<br></div><div>This forces the comp=
iler to consider other possible candidates.<br>Allowing zero sized arrays w=
ould cause the instantiation to succeed, which will obviously change the be=
haviour of existing programs.<br><br>=C2=A0 Tobias<br><br></div><div><br></=
div></div></blockquote><div>This is unfortunate. But can you come up with a=
 case where such SFINAE can actually be used? To me it seems that to use th=
is rule you would have to create a zero sized array first and then try to c=
all a function templated on the array size with it. But then you get a hard=
 error</div><div>for trying to make the array (under current rules)! Maybe =
there are more complicated cases but I think there has to be at least one t=
hat is possible to use today, or this SFINAE rule is superflous. Given actu=
al uses of this rule an assessment can be made whether breaking such code c=
an be accepted.</div></div></blockquote><div><br>One of the ways the SFINAE=
-rule is actually used:<br>=C2=A0 void foo(char (*)[...evaluates to 0 or &g=
t;0...] =3D0)<br>=C2=A0 void foo(...) =C2=A0 // other overloads<br><br>whic=
h is (currently) equivalent to (e.g.)</div><div><br></div><div>=C2=A0 std::=
disable_if&lt;...evaluates to false/true...&gt;::type foo();<br>=C2=A0 // o=
ther overloads<br><br>but would not, if zero-sized arrays are allowed (deve=
lopers would have to replace &quot;[value]&quot; with &quot;[2*(value)-1]&q=
uot; to get a negative-sized array for &quot;false&quot; to still fail SFIN=
AE).<br>=C2=A0=C2=A0<br>=C2=A0 Tobias<br>=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d5fea17c-34cc-41d4-9921-33e1dca3cc60%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d5fea17c-34cc-41d4-9921-33e1dca3cc60=
%40isocpp.org</a>.<br />

------=_Part_460_2054117735.1467796256105--

------=_Part_459_1680366961.1467796256104--

.


Author: Mathias Gaunard <mathias@gaunard.com>
Date: Wed, 6 Jul 2016 13:06:33 +0100
Raw View
--001a11401ac28ea1130536f66634
Content-Type: text/plain; charset=UTF-8

On 4 July 2016 at 16:15, Bengt Gustafsson <bengt.gustafsson@beamways.com>
wrote:

> I have been following the recent thread about empty base optimization, or
> rather, the lack of empty member optimization possibility. And today I
> again fell in the 0 sized array trap in metaprogramming, noticing that it
> creates quite a few problems requiring extra coding.
>
> This idea struck me to solve both of these issues at once by a few small
> changes:
>
> 1. Allow zero sized arrays in C++.
>
> No code would break by just allowing something previously forbidden. The
> problem with allowing this could have been to make up ones mind about what
> size such an array should report.
>
> 2. Define that a zero size array occupies zero bytes.
>
> As zero size arrays have never been allowed in C++ it can't be a breaking
> change to define that the now allowed zero size arrays actually consume no
> bytes regardless of the size of the element.
>

So you want

struct Foo
{
   char array[0];
   int value;
};

to be well-formed?

That's problematic for a number of reasons.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya-8Kn7VR3J0yxfPoR%2BzpDGDNxXSUwh4ZpD-t1KdbN9Prw%40mail.gmail.com.

--001a11401ac28ea1130536f66634
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 4=
 July 2016 at 16:15, Bengt Gustafsson <span dir=3D"ltr">&lt;<a href=3D"mail=
to:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafsson@beamwa=
ys.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr"><div>I have been following the recent thread about empty base optimiza=
tion, or rather, the lack of empty member optimization possibility. And tod=
ay I again fell in the 0 sized array trap in metaprogramming, noticing that=
 it creates quite a few problems requiring extra coding.</div><div><br></di=
v><div>This idea struck me to solve both of these issues at once by a few s=
mall changes:</div><div><br></div><div>1. Allow zero sized arrays in C++.</=
div><div><br></div><div>No code would break by just allowing something prev=
iously forbidden. The problem with allowing this could have been to make up=
 ones mind about what size such an array should report.</div><div><br></div=
><div>2. Define that a zero size array occupies zero bytes.</div><div><br><=
/div><div>As zero size arrays have never been allowed in C++ it can&#39;t b=
e a breaking change to define that the now allowed zero size arrays actuall=
y consume no bytes regardless of the size of the element.</div></div></bloc=
kquote><div><br></div><div>So you want<br><br></div><div>struct Foo</div><d=
iv>{</div><div>=C2=A0 =C2=A0char array[0];</div><div>=C2=A0 =C2=A0int value=
;</div><div>};</div><div><br></div><div>to be well-formed?<br><br>That&#39;=
s problematic for a number of reasons.</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALnjya-8Kn7VR3J0yxfPoR%2BzpDGDNxXSUw=
h4ZpD-t1KdbN9Prw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya-8Kn7VR3=
J0yxfPoR%2BzpDGDNxXSUwh4ZpD-t1KdbN9Prw%40mail.gmail.com</a>.<br />

--001a11401ac28ea1130536f66634--

.


Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Wed, 6 Jul 2016 14:25:07 +0100
Raw View
--Apple-Mail-9097D46E-DDCE-45CF-ACDC-74A4191AF82A
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



> On 6 Jul 2016, at 13:06, Mathias Gaunard <mathias@gaunard.com> wrote:
>=20
>> On 4 July 2016 at 16:15, Bengt Gustafsson <bengt.gustafsson@beamways.com=
> wrote:
>> I have been following the recent thread about empty base optimization, o=
r rather, the lack of empty member optimization possibility. And today I ag=
ain fell in the 0 sized array trap in metaprogramming, noticing that it cre=
ates quite a few problems requiring extra coding.
>>=20
>> This idea struck me to solve both of these issues at once by a few small=
 changes:
>>=20
>> 1. Allow zero sized arrays in C++.
>>=20
>> No code would break by just allowing something previously forbidden. The=
 problem with allowing this could have been to make up ones mind about what=
 size such an array should report.
>>=20
>> 2. Define that a zero size array occupies zero bytes.
>>=20
>> As zero size arrays have never been allowed in C++ it can't be a breakin=
g change to define that the now allowed zero size arrays actually consume n=
o bytes regardless of the size of the element.
>=20
> So you want
>=20
> struct Foo
> {
>    char array[0];
>    int value;
> };
>=20
> to be well-formed?
>=20
> That's problematic for a number of reasons.

Could you elaborate?

> --=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=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/CALnjya-8Kn7VR3J0yxfPoR%2BzpDGDNxXSUwh4ZpD-t1K=
dbN9Prw%40mail.gmail.com.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/DA1D891D-5D63-44A8-BA31-A8D9BCC9E684%40gmail.com=
..

--Apple-Mail-9097D46E-DDCE-45CF-ACDC-74A4191AF82A
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div></div><div><br></div><div><br>On 6=
 Jul 2016, at 13:06, Mathias Gaunard &lt;<a href=3D"mailto:mathias@gaunard.=
com">mathias@gaunard.com</a>&gt; wrote:<br><br></div><blockquote type=3D"ci=
te"><div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_qu=
ote">On 4 July 2016 at 16:15, Bengt Gustafsson <span dir=3D"ltr">&lt;<a hre=
f=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafss=
on@beamways.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div>I have been following the recent thread about empty base=
 optimization, or rather, the lack of empty member optimization possibility=
.. And today I again fell in the 0 sized array trap in metaprogramming, noti=
cing that it creates quite a few problems requiring extra coding.</div><div=
><br></div><div>This idea struck me to solve both of these issues at once b=
y a few small changes:</div><div><br></div><div>1. Allow zero sized arrays =
in C++.</div><div><br></div><div>No code would break by just allowing somet=
hing previously forbidden. The problem with allowing this could have been t=
o make up ones mind about what size such an array should report.</div><div>=
<br></div><div>2. Define that a zero size array occupies zero bytes.</div><=
div><br></div><div>As zero size arrays have never been allowed in C++ it ca=
n't be a breaking change to define that the now allowed zero size arrays ac=
tually consume no bytes regardless of the size of the element.</div></div><=
/blockquote><div><br></div><div>So you want<br><br></div><div>struct Foo</d=
iv><div>{</div><div>&nbsp; &nbsp;char array[0];</div><div>&nbsp; &nbsp;int =
value;</div><div>};</div><div><br></div><div>to be well-formed?<br><br>That=
's problematic for a number of reasons.</div></div></div></div></div></bloc=
kquote><div><br></div><div>Could you elaborate?</div><br><blockquote type=
=3D"cite"><div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups "=
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+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALnjya-8Kn7VR3J0yxfPoR%2BzpDGDNxXSUw=
h4ZpD-t1KdbN9Prw%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya-8Kn=
7VR3J0yxfPoR%2BzpDGDNxXSUwh4ZpD-t1KdbN9Prw%40mail.gmail.com</a>.<br>
</div></blockquote></body></html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/DA1D891D-5D63-44A8-BA31-A8D9BCC9E684%=
40gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/DA1D891D-5D63-44A8-BA31-A8D9BCC9E684%=
40gmail.com</a>.<br />

--Apple-Mail-9097D46E-DDCE-45CF-ACDC-74A4191AF82A--

.


Author: Mathias Gaunard <mathias@gaunard.com>
Date: Wed, 6 Jul 2016 16:14:55 +0100
Raw View
--001a113fc3a431f09b0536f9081b
Content-Type: text/plain; charset=UTF-8

On 6 July 2016 at 14:25, Jonathan Coe <jonathanbcoe@gmail.com> wrote:

>
> On 6 Jul 2016, at 13:06, Mathias Gaunard <mathias@gaunard.com> wrote:
>
>
> So you want
>
> struct Foo
> {
>    char array[0];
>    int value;
> };
>
> to be well-formed?
>
> That's problematic for a number of reasons.
>
>
> Could you elaborate?
>

I'm pretty sure the object model requires members to have different
offsets, there is also the issue that you get aliasing of unrelated types
etc.
It would be best to discuss this with core experts.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya9%3D225vTNHB4ouOp0Rj1%3Doz4N5eAutkWR2Sk9Dz%2B3kOUA%40mail.gmail.com.

--001a113fc3a431f09b0536f9081b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 6=
 July 2016 at 14:25, Jonathan Coe <span dir=3D"ltr">&lt;<a href=3D"mailto:j=
onathanbcoe@gmail.com" target=3D"_blank">jonathanbcoe@gmail.com</a>&gt;</sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div><div cl=
ass=3D"h5"><div></div><div><br></div><div>On 6 Jul 2016, at 13:06, Mathias =
Gaunard &lt;<a href=3D"mailto:mathias@gaunard.com" target=3D"_blank">mathia=
s@gaunard.com</a>&gt; wrote:</div><blockquote type=3D"cite"><div dir=3D"ltr=
"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><br></div><div=
>So you want<br><br></div><div>struct Foo</div><div>{</div><div>=C2=A0 =C2=
=A0char array[0];</div><div>=C2=A0 =C2=A0int value;</div><div>};</div><div>=
<br></div><div>to be well-formed?<br><br>That&#39;s problematic for a numbe=
r of reasons.</div></div></div></div></blockquote><div><br></div></div></di=
v><div>Could you elaborate?</div></div></blockquote><div><br></div><div>I&#=
39;m pretty sure the object model requires members to have different offset=
s, there is also the issue that you get aliasing of unrelated types etc.</d=
iv><div>It would be best to discuss this with core experts.</div></div></di=
v></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALnjya9%3D225vTNHB4ouOp0Rj1%3Doz4N5e=
AutkWR2Sk9Dz%2B3kOUA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya9%3D=
225vTNHB4ouOp0Rj1%3Doz4N5eAutkWR2Sk9Dz%2B3kOUA%40mail.gmail.com</a>.<br />

--001a113fc3a431f09b0536f9081b--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 6 Jul 2016 08:34:25 -0700 (PDT)
Raw View
------=_Part_912_1851509472.1467819265686
Content-Type: multipart/alternative;
 boundary="----=_Part_913_1525079176.1467819265687"

------=_Part_913_1525079176.1467819265687
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, July 6, 2016 at 4:59:56 AM UTC-4, Bengt Gustafsson wrote:
>
> I see no problem with defining the meanings you are after here. Use logic=
..=20
> See also below.
>

For something as complex as stateless objects, it is *you* who needs to do=
=20
the work to come up with all of the corner cases. Or at least a good-faith=
=20
effort at it. I'm not saying that you need to have complete standards=20
wording at this point, but demonstraiting an understanding of most of the=
=20
problems in this would go a long way in making others feel confident that=
=20
you know what you're talking about.

Den m=C3=A5ndag 4 juli 2016 kl. 18:30:24 UTC+2 skrev Nicol Bolas:
>>
>>
>>
>> On Monday, July 4, 2016 at 11:15:15 AM UTC-4, Bengt Gustafsson wrote:
>>>
>>> I have been following the recent thread about empty base optimization,=
=20
>>> or rather, the lack of empty member optimization possibility. And today=
 I=20
>>> again fell in the 0 sized array trap in metaprogramming, noticing that =
it=20
>>> creates quite a few problems requiring extra coding.
>>>
>>> This idea struck me to solve both of these issues at once by a few smal=
l=20
>>> changes:
>>>
>>> 1. Allow zero sized arrays in C++.
>>>
>>> No code would break by just allowing something previously forbidden. Th=
e=20
>>> problem with allowing this could have been to make up ones mind about w=
hat=20
>>> size such an array should report.
>>>
>>
>> Allow them to do... what?
>>
> Be declared. Have their address taken. Said address being being that of=
=20
> the first addressable byte after the previous variable in the scope.
>

So, given this:

struct Foo
{
  int f;
  float g[0];
};

Foo foo;
int j;

What will the address of `foo.g` be? You say that it is "first addressable=
=20
byte after" `foo.f`. If `g` is not supposed to take up space within `Foo`,=
=20
then `Foo` should be layout-compatible with a struct with a single `int`=20
member (and if *that's* not going to be guaranteed, then the whole proposal=
=20
solves nothing. That is, after all the whole point of stateless=20
subobjects). The size and align of such a struct will likely be the sizeof=
=20
and alignof an `int`.

Which means that the "first addressable byte" after `foo.f` is... *outside*=
=20
of `Foo`. Indeed, given the above, it is entirely possible that the address=
=20
of `g` is the same address as `j`, a completely unrelated variable.

Which now means that two unrelated objects have the same address. The=20
object rules of C++ do not permit two unrelated objects to live in the same=
=20
address. So there's another rule that you'll have to change.

Not to mention that the address of a subobject of a type is somewhere=20
*outside* of that object's storage. It's not clear if that breaks a rule of=
=20
C++ per-se, since all prior addresses were based on the subobject's=20
storage, and by definition stateless subobjects don't have storage. But=20
even so, it's exceedingly bizarre.

From this follows that begin() and end() on zero sized arrays both return=
=20
> this address, so that range based for loops 0 times.
> =20
>
>> =20
>>
>>> 2. Define that a zero size array occupies zero bytes.
>>>
>>
>> The C++ object model requires that objects take up storage. If you have=
=20
>> an array that has no objects in it, then you clearly cannot use objects=
=20
>> that don't exist. So having an array of 0 objects means that you can't d=
o=20
>> anything with `a[0]`.
>>
> Of course not, just as with an array sized 1 you can't do anything with=
=20
> a[1], because there is nothing there.
>
> Of course any writing in the standard document mentioning that all C++=20
> objects must take up storage must be amended with a clause that excepts=
=20
> zero sized arrays.
>

And what about the fallout from changing *that*?

How do zero-sized arrays affect the trivial copyability of the type? Can=20
you manually copy a zero-sized subobject?

What is the size of a zero-sized array?

Equally importantly, if you can make the rules allow a zero-sized array,=20
then you have all the groundwork you need (standards wise) to just declare=
=20
that a particular subobject will be zero size.

So what's the point of using this arcane zero-sized array thing if you can=
=20
use actual syntax?

Merely permitting the syntax doesn't work. You have to actually define what=
=20
>> that *means*. Whether it's a zero-sized array or an object that takes no=
=20
>> storage or whatever, you still need to do the hard work of deciding what=
=20
>> that actually means.
>>
> I think all that is needed is stated above.
>

I've looked into this problem before on several occasions. And while I am=
=20
hardly a master of the standards wording, I can tell you that even after=20
significant research, I still cannot claim to fully understand the=20
ramifications of making such a change, regardless of how you declare such=
=20
subobjects.

Consider your resolution to the question of what the address of such a=20
variable is. That was a blatant violation of the strict aliasing rule. And=
=20
the strict aliasing rule is pretty much problem #1 for *any* stateless=20
subobject proposal (since the subobject will likely have to have a pointer=
=20
address in its container object, which may be another object type). So=20
anyone who even considers proposing such a thing needs to have at least a=
=20
cursory understanding of that rule. And yet, you did not demonstrate such=
=20
an understanding.

So I submit that what you've said above is far from all that needs to be=20
said.

And for a zero-sized array, you also have to decide what it means for the=
=20
>> array to decay to a pointer.
>>
> It decays to its address as defined above. At this address there is no=20
> valid object, just as there isnt when you do &a[1] for a 1-long array=20
> today. I fail to see a problem here.=20
>

Wait; if there's no valid object there... what good is making such a=20
declaration?

Is it legal to call member functions for such a non-object? No; such member=
=20
functions will have a `this` pointer to an invalid object. As such, it is=
=20
functionally equivalent to calling a member function on a `nullptr` object.

So if you can't actually call member functions of zero-sized objects,=20
what's the point of having them at all?

How we declare that a variable takes up no storage is not the hard part of=
=20
>> having stateless members. Whether it's a magic standard library type, a=
=20
>> zero-size array, or a new keyword, that's the easy part. The hard part i=
s=20
>> deciding what they mean, how pointers to them work, how they get copied,=
=20
>> etc.
>>
> An advantage of using the zero-sized array idiom is that the question of=
=20
> "how do I iterate over an array of zero sized objects" does not come up a=
s=20
> a separate issue.
>

Sure it does. You just haven't thought it through:

struct Bar
{
  float f[20][0];
};

See? An array of 20 zero-sized objects.

In any case, it's easy enough to simply outright forbid having arrays of=20
stateless objects. But your proposal makes that no easier than any other.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/97fddbdb-3885-4200-9b48-c9919857d3ee%40isocpp.or=
g.

------=_Part_913_1525079176.1467819265687
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, July 6, 2016 at 4:59:56 AM UTC-4, Bengt Gust=
afsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
I see no problem with defining the meanings you are after here. Use logic. =
See also below.<br></div></blockquote><div><br>For something as complex as =
stateless objects, it is <i>you</i> who needs to do the work to come up wit=
h all of the corner cases. Or at least a good-faith effort at it. I&#39;m n=
ot saying that you need to have complete standards wording at this point, b=
ut demonstraiting an understanding of most of the problems in this would go=
 a long way in making others feel confident that you know what you&#39;re t=
alking about.<br><br></div><div></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr">Den m=C3=A5ndag 4 juli 2016 kl. 18:30:24 UTC+2 skr=
ev Nicol Bolas:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br=
><br>On Monday, July 4, 2016 at 11:15:15 AM UTC-4, Bengt Gustafsson wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I have been fo=
llowing the recent thread about empty base optimization, or rather, the lac=
k of empty member optimization possibility. And today I again fell in the 0=
 sized array trap in metaprogramming, noticing that it creates quite a few =
problems requiring extra coding.</div><div><br></div><div>This idea struck =
me to solve both of these issues at once by a few small changes:</div><div>=
<br></div><div>1. Allow zero sized arrays in C++.</div><div><br></div><div>=
No code would break by just allowing something previously forbidden. The pr=
oblem with allowing this could have been to make up ones mind about what si=
ze such an array should report.</div></div></blockquote><div><br>Allow them=
 to do... what?<br></div></div></blockquote><div>Be declared. Have their ad=
dress taken. Said address being being that of the first addressable byte af=
ter the previous variable in the scope.</div></div></blockquote><div><br>So=
, given this:<br><br><div class=3D"prettyprint" style=3D"background-color: =
rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; =
border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div=
 class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">float</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> g</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">];=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> j</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span></div></code></div><br>What will the address of `foo.g` be? You say=
 that it is &quot;first addressable byte after&quot; `foo.f`. If `g` is not=
 supposed to take up space within `Foo`, then `Foo` should be layout-compat=
ible with a struct with a single `int` member (and if <i>that&#39;s</i> not=
 going to be guaranteed, then the whole proposal solves nothing. That is, a=
fter all the whole point of stateless subobjects). The size and align of su=
ch a struct will likely be the sizeof and alignof an `int`.<br><br>Which me=
ans that the &quot;first addressable byte&quot; after `foo.f` is... <i>outs=
ide</i> of `Foo`. Indeed, given the above, it is entirely possible that the=
 address of `g` is the same address as `j`, a completely unrelated variable=
..<br><br>Which now means that two unrelated objects have the same address. =
The object rules of C++ do not permit two unrelated objects to live in the =
same address. So there&#39;s another rule that you&#39;ll have to change.<b=
r><br>Not to mention that the address of a subobject of a type is somewhere=
 <i>outside</i> of that object&#39;s storage. It&#39;s not clear if that br=
eaks a rule of C++ per-se, since all prior addresses were based on the subo=
bject&#39;s storage, and by definition stateless subobjects don&#39;t have =
storage. But even so, it&#39;s exceedingly bizarre.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>From this follows =
that begin() and end() on zero sized arrays both return this address, so th=
at range based for loops 0 times.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>2. Define that a ze=
ro size array occupies zero bytes.</div></div></blockquote><div><br>The C++=
 object model requires that objects take up storage. If you have=20
an array that has no objects in it, then you clearly cannot use objects=20
that don&#39;t exist. So having an array of 0 objects means that you can&#3=
9;t=20
do anything with `a[0]`.<br></div></div></blockquote><div>Of course not, ju=
st as with an array sized 1 you can&#39;t do anything with a[1], because th=
ere is nothing there.</div><div><br></div><div>Of course any writing in the=
 standard document mentioning that all C++ objects must take up storage mus=
t be amended with a clause that excepts zero sized arrays.</div></div></blo=
ckquote><div><br>And what about the fallout from changing <i>that</i>?<br><=
br>How do zero-sized arrays affect the trivial copyability of the type? Can=
 you manually copy a zero-sized subobject?<br><br>What is the size of a zer=
o-sized array?<br><br>Equally importantly, if you can make the rules allow =
a zero-sized array, then you have all the groundwork you need (standards wi=
se) to just declare that a particular subobject will be zero size.<br><br>S=
o what&#39;s the point of using this arcane zero-sized array thing if you c=
an use actual syntax?<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr"><div>Merely permitting the syntax doesn&#39;t work. You have to actual=
ly define what that <i>means</i>.
 Whether it&#39;s a zero-sized array or an object that takes no storage or=
=20
whatever, you still need to do the hard work of deciding what that=20
actually means.<br></div></div></blockquote><div>I think all that is needed=
 is stated above.</div></div></blockquote><div><br>I&#39;ve looked into thi=
s problem before on several occasions. And while I=20
am hardly a master of the standards wording, I can tell you that even=20
after significant research, I still cannot claim to fully understand the
 ramifications of making such a change, regardless of how you declare=20
such subobjects.<br><br>Consider your resolution to the question of what th=
e address of such a variable is. That was a blatant violation of the strict=
 aliasing rule. And the strict aliasing rule is pretty much problem #1 for =
<i>any</i> stateless subobject proposal (since the subobject will likely ha=
ve to have a pointer address in its container object, which may be another =
object type). So anyone who even considers proposing such a thing needs to =
have at least a cursory understanding of that rule. And yet, you did not de=
monstrate such an understanding.<br><br>So I submit that what you&#39;ve sa=
id above is far from all that needs to be said.<br><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div>And for a zero-sized array, you also hav=
e to decide what it means for the array to decay to a pointer.<br></div></d=
iv></blockquote><div>It decays to its address as defined above. At this add=
ress there is no valid object, just as there isnt when you do &amp;a[1] for=
 a 1-long array today. I fail to see a problem here.=C2=A0</div></div></blo=
ckquote><div><br>Wait; if there&#39;s no valid object there... what good is=
 making such a declaration?<br><br>Is it legal to call member functions for=
 such a non-object? No; such member functions will have a `this` pointer to=
 an invalid object. As such, it is functionally equivalent to calling a mem=
ber function on a `nullptr` object.<br><br>So if you can&#39;t actually cal=
l member functions of zero-sized objects, what&#39;s the point of having th=
em at all?<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Ho=
w we declare that a variable takes up no storage is not the hard part of ha=
ving stateless members. Whether it&#39;s a magic standard library type, a z=
ero-size array, or a new keyword, that&#39;s the easy part. The hard part i=
s deciding what they mean, how pointers to them work, how they get copied, =
etc.<br></div></div></blockquote><div>An advantage of using the zero-sized =
array idiom is that the question of &quot;how do I iterate over an array of=
 zero sized objects&quot; does not come up as a separate issue.</div></div>=
</blockquote><div><br>Sure it does. You just haven&#39;t thought it through=
:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
uct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Bar</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">float</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">[</span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">20</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">][</span><span style=3D"color: #066;" class=3D"styled-by-prettify"=
>0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">];</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">};</span></div></code>=
</div><br>See? An array of 20 zero-sized objects.<br><br>In any case, it&#3=
9;s easy enough to simply outright forbid having arrays of stateless object=
s. But your proposal makes that no easier than any other.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/97fddbdb-3885-4200-9b48-c9919857d3ee%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/97fddbdb-3885-4200-9b48-c9919857d3ee=
%40isocpp.org</a>.<br />

------=_Part_913_1525079176.1467819265687--

------=_Part_912_1851509472.1467819265686--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 7 Jul 2016 17:09:35 -0700
Raw View
--001a114e572a2d83580537149e62
Content-Type: text/plain; charset=UTF-8

On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> I have been following the recent thread about empty base optimization, or
> rather, the lack of empty member optimization possibility. And today I
> again fell in the 0 sized array trap in metaprogramming, noticing that it
> creates quite a few problems requiring extra coding.
>

When I started working on Regular Void (p0146) I initially explored size 0
types but decided to postpone the effort because it has some difficult
practical concerns regarding backwards compatibility. I think it might be
possible that we will eventually get to a point where the language allows
size 0 types, but it is not something that we can just start introducing
(arrays or otherwise) without broader considerations. If the language had
size 0 types to begin with then there would be no potential issues, but I
half-suspect that the transition to a world where size 0 types exist may be
more difficult than people would care to accept.

Here's a brief summary of my current conclusions. I'd like to eventually
explore this again once Regular Void either goes into the language or is
killed.

1) In order for size 0 types to be useful as a means of minimizing storage,
we'd effectively have to change aliasing rules. No two objects of the same
type can occupy the same address in C++ as it currently is, which
user-level code can and does exploit. We'd want size 0 objects to able to
[effectively] share an address. This is true even if you only limit size 0
types to arrays of size 0.
2) The more important concern, IMO, is that size 0 types fundamentally
break our assumption that raw pointer types are able to act as iterators
into arrays. Again, this problem still exists and needs to be...
addressed... (heh) even if you only allow arrays of size 0 and not more
general size 0 types.  A simple example of this is as follows:

// This iterates 5 times
int a[5] = {};
for( auto& elem : a )
{
  // ...do whatever...
}

// This iterates 0 times
using foo = int[0];
foo b[5] = {};
for( auto& elem : b )
{
  // ...do whatever...
}

The above might seem contrived, but it's not at all. Once you allow size 0
types, they can easily turn up as dependent types in generic code for which
arrays can be made. IMO, this issue is a symptom of the language
incorrectly conflating an address and an iterator. For example, in a
language with size 0 types, the above code could be made to work perfectly
fine if it considered an iterator into an array whose element type is size
0 to be something other than a pointer (i.e. simply an integer value
corresponding to the array index). Once that separation is made, you can go
back to easily iterating over the arrays no matter what the element size
is, but the underlying implication is that any generic code in C++ today
that assumes a pointer is a valid iterator into an array would now be
broken for empty types. That might not be a huge deal if you don't allow
"struct foo {};" to be a size 0 type, but that also rules out one of the
main reasons that people want size 0 types to begin with. Allowing size 0
arrays might seem like an easier start, but I think you technically have to
solve all of the same problems anyway, even though those problems happen to
be less-likely to come up in practice.

Ultimately, I think that if we get size 0 types, we wouldn't just special
case arrays of size 0. An array is just an object and it being size 0
requires the same considerations as other types being size 0. In the end,
if we allow size 0 types, my personal conclusion is that:

1) It shouldn't be restricted to size 0 arrays
2) Different objects of the same (empty) type can share the same address
3) std::array_iterator< /*array type*/ > or something similar yields an
appropriate iterator type for the array (isn't a pointer type when the
element type is size 0)
4) [Unfortunately] for practicality, user-defined types should at least
initially have some kind of specifier-hint that tells the implementation
that the type is allowed to be size 0 if it happens to have no members or
all of the members/bases are also size 0. This is subtle, but
implementations all of a sudden having something like "struct foo {};"
become size 0 overnight would never happen, and the same goes for struct
foo { /*empty type members*/ };). Because of that, at least initially,
people would have to explicitly request the ability for their type to
potentially be size 0 when all other conditions allow it, otherwise they
wouldn't be able to take advantage of it in practice during the transition.

In other words:

struct /*some specifier*/ foo { /*potentially some datamembers which may or
may not be empty*/ };

where the existence of /*some specifier*/ allows the implementation to let
"foo" be size 0.

Anyway, those were just my thoughts prior to putting things on hold, but I
still stand by most of that assessment.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEnWzX%3DcNwdCfGHq--Dg1j%3Dj3j9HK8oDjSkRKAcDRPjLhw%40mail.gmail.com.

--001a114e572a2d83580537149e62
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson <span dir=3D"ltr">&lt;<a href=
=3D"mailto:bengt.gustafsson@beamways.com">bengt.gustafsson@beamways.com</a>=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-co=
lor:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>I have been fo=
llowing the recent thread about empty base optimization, or rather, the lac=
k of empty member optimization possibility. And today I again fell in the 0=
 sized array trap in metaprogramming, noticing that it creates quite a few =
problems requiring extra coding.</div></div></blockquote><div><br></div><di=
v>When I started working on Regular Void (p0146) I initially explored size =
0 types but decided to postpone the effort because it has some difficult pr=
actical concerns regarding backwards compatibility. I think it might be pos=
sible that we will eventually get to a point where the language allows size=
 0 types, but it is not something that we can just start introducing (array=
s or otherwise) without broader considerations. If the language had size 0 =
types to begin with then there would be no potential issues, but I half-sus=
pect that the transition to a world where size 0 types exist may be more di=
fficult than people would care to accept.</div><div><br></div><div>Here&#39=
;s a brief summary of my current conclusions. I&#39;d like to eventually ex=
plore this again once Regular Void either goes into the language or is kill=
ed.</div><div><br></div><div>1) In order for size 0 types to be useful as a=
 means of minimizing storage, we&#39;d effectively have to change aliasing =
rules. No two objects of the same type can occupy the same address in C++ a=
s it currently is, which user-level code can and does exploit. We&#39;d wan=
t size 0 objects to able to [effectively] share an address. This is true ev=
en if you only limit size 0 types to arrays of size 0.</div><div>2) The mor=
e important concern, IMO, is that size 0 types fundamentally break our assu=
mption that raw pointer types are able to act as iterators into arrays. Aga=
in, this problem still exists and needs to be... addressed... (heh)=C2=A0ev=
en if you only allow arrays of size 0 and not more general size 0 types.=C2=
=A0 A simple example of this is as follows:</div><div><br></div><div>// Thi=
s iterates 5 times</div><div><div>int a[5] =3D {};</div><div>for( auto&amp;=
 elem : a )</div><div>{</div><div>=C2=A0 // ...do whatever...</div><div>}</=
div></div><div><br></div><div>// This iterates 0 times</div><div>using foo =
=3D int[0];</div><div>foo b[5] =3D {};</div><div>for( auto&amp; elem : b )<=
/div><div>{</div>=C2=A0 // ...do whatever...<div>}</div><div><br></div><div=
>The above might seem contrived, but it&#39;s not at all. Once you allow si=
ze 0 types, they can easily turn up as dependent types in generic code for =
which arrays can be made. IMO, this issue is a symptom of the language inco=
rrectly conflating an address and an iterator. For example, in a language w=
ith size 0 types, the above code could be made to work perfectly fine if it=
 considered an iterator into an array whose element type is size 0 to be so=
mething other than a pointer (i.e. simply an integer value corresponding to=
 the array index). Once that separation is made, you can go back to easily =
iterating over the arrays no matter what the element size is, but the under=
lying implication is that any generic code in C++ today that assumes a poin=
ter is a valid iterator into an array would now be broken for empty types. =
That might not be a huge deal if you don&#39;t allow &quot;struct foo {};&q=
uot; to be a size 0 type, but that also rules out one of the main reasons t=
hat people want size 0 types to begin with. Allowing size 0 arrays might se=
em like an easier start, but I think you technically have to solve all of t=
he same problems anyway, even though those problems happen to be less-likel=
y to come up in practice.</div><div><br></div><div>Ultimately, I think that=
 if we get size 0 types, we wouldn&#39;t just special case arrays of size 0=
.. An array is just an object and it being size 0 requires the same consider=
ations as other types being size 0. In the end, if we allow size 0 types, m=
y personal conclusion is that:</div><div><br></div><div>1) It shouldn&#39;t=
 be restricted to size 0 arrays</div><div>2) Different objects of the same =
(empty) type can share the same address</div><div>3) std::array_iterator&lt=
; /*array type*/ &gt; or something similar yields an appropriate iterator t=
ype for the array (isn&#39;t a pointer type when the element type is size 0=
)</div><div>4) [Unfortunately] for practicality, user-defined types should =
at least initially have some kind of specifier-hint that tells the implemen=
tation that the type is allowed to be size 0 if it happens to have no membe=
rs or all of the members/bases are also size 0. This is subtle, but impleme=
ntations all of a sudden having something like &quot;struct foo {};&quot; b=
ecome size 0 overnight would never happen, and the same goes for struct foo=
 { /*empty type members*/ };). Because of that, at least initially, people =
would have to explicitly request the ability for their type to potentially =
be size 0 when all other conditions allow it, otherwise they wouldn&#39;t b=
e able to take advantage of it in practice during the transition.</div><div=
><br></div><div>In other words:</div><div><br></div><div>struct /*some spec=
ifier*/=C2=A0foo { /*potentially some datamembers which may or may not be e=
mpty*/ };</div><div><br></div><div>where the existence of /*some specifier*=
/ allows the implementation to let &quot;foo&quot; be size 0.</div><div><br=
></div><div>Anyway, those were just my thoughts prior to putting things on =
hold, but I still stand by most of that assessment.</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEnWzX%3DcNwdCfGHq--Dg1j%3Dj3j9H=
K8oDjSkRKAcDRPjLhw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEnWzX%3=
DcNwdCfGHq--Dg1j%3Dj3j9HK8oDjSkRKAcDRPjLhw%40mail.gmail.com</a>.<br />

--001a114e572a2d83580537149e62--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 7 Jul 2016 19:21:28 -0700 (PDT)
Raw View
------=_Part_4242_587393052.1467944488295
Content-Type: multipart/alternative;
 boundary="----=_Part_4243_845724229.1467944488295"

------=_Part_4243_845724229.1467944488295
Content-Type: text/plain; charset=UTF-8

On Thursday, July 7, 2016 at 8:09:37 PM UTC-4, Matt Calabrese wrote:
>
> On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson <bengt.gu...@beamways.com
> <javascript:>> wrote:
>
>> I have been following the recent thread about empty base optimization, or
>> rather, the lack of empty member optimization possibility. And today I
>> again fell in the 0 sized array trap in metaprogramming, noticing that it
>> creates quite a few problems requiring extra coding.
>>
>
> When I started working on Regular Void (p0146) I initially explored size 0
> types but decided to postpone the effort because it has some difficult
> practical concerns regarding backwards compatibility. I think it might be
> possible that we will eventually get to a point where the language allows
> size 0 types, but it is not something that we can just start introducing
> (arrays or otherwise) without broader considerations. If the language had
> size 0 types to begin with then there would be no potential issues, but I
> half-suspect that the transition to a world where size 0 types exist may be
> more difficult than people would care to accept.
>
> Here's a brief summary of my current conclusions. I'd like to eventually
> explore this again once Regular Void either goes into the language or is
> killed.
>
> 1) In order for size 0 types to be useful as a means of minimizing
> storage, we'd effectively have to change aliasing rules. No two objects of
> the same type can occupy the same address in C++ as it currently is, which
> user-level code can and does exploit.
>

Actually that's not quite true, and it is this exception that focused my
stateless subobject idea (that I'm still occasionally refining). There are
certain cases where two objects can have the same address. Namely, base
class subobjects and their derived class. This is why [basic.lval]/10 has
an explicit exception in the aliasing rules for types which are "similar
to" the actual object's type.

The way I see it, the best way forward for stateless subobjects is not to
make them zero-sized. It is to make them simply not take up space in the
layout of the object they exist within. We permit their addresses to alias
with anything, by adding them as an exception to the aliasing rules.

Namely, it is not undefined behavior to access the stored value of an
object through a glvalue to a stateless subobject. This should be safe
since, by definition, stateless objects *have no value*. Empty objects have
a region of storage, but they cannot do anything with it. So it doesn't
matter if their regions of storage overlap with someone else's.

This would require going through the standard and making changes where
needed so that this doesn't break things. Like making trivial copying into
a stateless subobject being undefined behavior (just as it is for copying
into base subobjects of any kind), for example. Since stateless subobjects
can overlap with anything, their addresses do not represent unique storage.

We'd want size 0 objects to able to [effectively] share an address. This is
> true even if you only limit size 0 types to arrays of size 0.
> 2) The more important concern, IMO, is that size 0 types fundamentally
> break our assumption that raw pointer types are able to act as iterators
> into arrays. Again, this problem still exists and needs to be...
> addressed... (heh) even if you only allow arrays of size 0 and not more
> general size 0 types.  A simple example of this is as follows:
>
> // This iterates 5 times
> int a[5] = {};
> for( auto& elem : a )
> {
>   // ...do whatever...
> }
>
> // This iterates 0 times
> using foo = int[0];
> foo b[5] = {};
> for( auto& elem : b )
> {
>   // ...do whatever...
> }
>
> The above might seem contrived, but it's not at all. Once you allow size 0
> types, they can easily turn up as dependent types in generic code for which
> arrays can be made. IMO, this issue is a symptom of the language
> incorrectly conflating an address and an iterator. For example, in a
> language with size 0 types, the above code could be made to work perfectly
> fine if it considered an iterator into an array whose element type is size
> 0 to be something other than a pointer (i.e. simply an integer value
> corresponding to the array index). Once that separation is made, you can go
> back to easily iterating over the arrays no matter what the element size
> is, but the underlying implication is that any generic code in C++ today
> that assumes a pointer is a valid iterator into an array would now be
> broken for empty types. That might not be a huge deal if you don't allow
> "struct foo {};" to be a size 0 type, but that also rules out one of the
> main reasons that people want size 0 types to begin with. Allowing size 0
> arrays might seem like an easier start, but I think you technically have to
> solve all of the same problems anyway, even though those problems happen to
> be less-likely to come up in practice.
>
> Ultimately, I think that if we get size 0 types, we wouldn't just special
> case arrays of size 0. An array is just an object and it being size 0
> requires the same considerations as other types being size 0. In the end,
> if we allow size 0 types, my personal conclusion is that:
>
> 1) It shouldn't be restricted to size 0 arrays
> 2) Different objects of the same (empty) type can share the same address
> 3) std::array_iterator< /*array type*/ > or something similar yields an
> appropriate iterator type for the array (isn't a pointer type when the
> element type is size 0)
> 4) [Unfortunately] for practicality, user-defined types should at least
> initially have some kind of specifier-hint that tells the implementation
> that the type is allowed to be size 0 if it happens to have no members or
> all of the members/bases are also size 0. This is subtle, but
> implementations all of a sudden having something like "struct foo {};"
> become size 0 overnight would never happen, and the same goes for struct
> foo { /*empty type members*/ };). Because of that, at least initially,
> people would have to explicitly request the ability for their type to
> potentially be size 0 when all other conditions allow it, otherwise they
> wouldn't be able to take advantage of it in practice during the transition.
>

I would say that the requirement should be stronger than that. Your idea is
to make it a hint, that implementations *may* allow the size to be 0. I say
that it should be *enforced*. If you declare that a type is zero-sized,
then put things in it that aren't themselves zero-sized, then I would say
that your code is *incoherent* and does not deserve to compile. It seems
likely to me that a user who declares that a type will be zero-sized, then
does something that makes this impossible has made a mistake.

But at the same time, I do think it is important that users can make a
distinction between "This type *will be* zero-sided" and "If my
declarations make this empty, then it should be zero-sized".


> In other words:
>
> struct /*some specifier*/ foo { /*potentially some datamembers which may
> or may not be empty*/ };
>
> where the existence of /*some specifier*/ allows the implementation to let
> "foo" be size 0.
>

As I've refined my own stateless types idea, I came to realize something.
While it is useful to be able to declare that a type will be stateless, it
is also useful to declare that a type which was not explicitly declared
stateless can be *used* as a stateless subobject. That way, you don't
create a rigid separation between the world of stateless things and the
world of non-stateless things.

If someone passes you an allocator that is an empty type, but they didn't
declare it stateless, that's OK: you can fix that at the point of use.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8a31c6b9-eba5-4e0a-9b9c-431f3a79c727%40isocpp.org.

------=_Part_4243_845724229.1467944488295
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, July 7, 2016 at 8:09:37 PM UTC-4, Matt Calabr=
ese wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v><div class=3D"gmail_quote">On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafss=
on <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfu=
scated-mailto=3D"4ld7g3lCCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D=
&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:=
&#39;;return true;">bengt.gu...@beamways.com</a><wbr>&gt;</span> wrote:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);p=
adding-left:1ex"><div dir=3D"ltr"><div>I have been following the recent thr=
ead about empty base optimization, or rather, the lack of empty member opti=
mization possibility. And today I again fell in the 0 sized array trap in m=
etaprogramming, noticing that it creates quite a few problems requiring ext=
ra coding.</div></div></blockquote><div><br></div><div>When I started worki=
ng on Regular Void (p0146) I initially explored size 0 types but decided to=
 postpone the effort because it has some difficult practical concerns regar=
ding backwards compatibility. I think it might be possible that we will eve=
ntually get to a point where the language allows size 0 types, but it is no=
t something that we can just start introducing (arrays or otherwise) withou=
t broader considerations. If the language had size 0 types to begin with th=
en there would be no potential issues, but I half-suspect that the transiti=
on to a world where size 0 types exist may be more difficult than people wo=
uld care to accept.</div><div><br></div><div>Here&#39;s a brief summary of =
my current conclusions. I&#39;d like to eventually explore this again once =
Regular Void either goes into the language or is killed.</div><div><br></di=
v><div>1) In order for size 0 types to be useful as a means of minimizing s=
torage, we&#39;d effectively have to change aliasing rules. No two objects =
of the same type can occupy the same address in C++ as it currently is, whi=
ch user-level code can and does exploit.</div></div></div></div></blockquot=
e><div><br>Actually that&#39;s not quite true, and it is this exception tha=
t focused my stateless subobject idea (that I&#39;m still occasionally refi=
ning). There are certain cases where two objects can have the same address.=
 Namely, base class subobjects and their derived class. This is why [basic.=
lval]/10 has an explicit exception in the aliasing rules for types which ar=
e &quot;similar to&quot; the actual object&#39;s type.<br><br>The way I see=
 it, the best way forward for stateless subobjects is not to make them zero=
-sized. It is to make them simply not take up space in the layout of the ob=
ject they exist within. We permit their addresses to alias with anything, b=
y adding them as an exception to the aliasing rules.<br><br>Namely, it is n=
ot undefined behavior to access the stored value of an object through a glv=
alue to a stateless subobject. This should be safe since, by definition, st=
ateless objects <i>have no value</i>. Empty objects have a region of storag=
e, but they cannot do anything with it. So it doesn&#39;t matter if their r=
egions of storage overlap with someone else&#39;s.<br><br>This would requir=
e going through the standard and making changes where needed so that this d=
oesn&#39;t break things. Like making trivial copying into a stateless subob=
ject being undefined behavior (just as it is for copying into base subobjec=
ts of any kind), for example. Since stateless subobjects can overlap with a=
nything, their addresses do not represent unique storage.<br><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><div> We&#39;d want size 0 objects to able to [effectively=
] share an address. This is true even if you only limit size 0 types to arr=
ays of size 0.</div><div>2) The more important concern, IMO, is that size 0=
 types fundamentally break our assumption that raw pointer types are able t=
o act as iterators into arrays. Again, this problem still exists and needs =
to be... addressed... (heh)=C2=A0even if you only allow arrays of size 0 an=
d not more general size 0 types.=C2=A0 A simple example of this is as follo=
ws:</div><div><br></div><div>// This iterates 5 times</div><div><div>int a[=
5] =3D {};</div><div>for( auto&amp; elem : a )</div><div>{</div><div>=C2=A0=
 // ...do whatever...</div><div>}</div></div><div><br></div><div>// This it=
erates 0 times</div><div>using foo =3D int[0];</div><div>foo b[5] =3D {};</=
div><div>for( auto&amp; elem : b )</div><div>{</div>=C2=A0 // ...do whateve=
r...<div>}</div><div><br></div><div>The above might seem contrived, but it&=
#39;s not at all. Once you allow size 0 types, they can easily turn up as d=
ependent types in generic code for which arrays can be made. IMO, this issu=
e is a symptom of the language incorrectly conflating an address and an ite=
rator. For example, in a language with size 0 types, the above code could b=
e made to work perfectly fine if it considered an iterator into an array wh=
ose element type is size 0 to be something other than a pointer (i.e. simpl=
y an integer value corresponding to the array index). Once that separation =
is made, you can go back to easily iterating over the arrays no matter what=
 the element size is, but the underlying implication is that any generic co=
de in C++ today that assumes a pointer is a valid iterator into an array wo=
uld now be broken for empty types. That might not be a huge deal if you don=
&#39;t allow &quot;struct foo {};&quot; to be a size 0 type, but that also =
rules out one of the main reasons that people want size 0 types to begin wi=
th. Allowing size 0 arrays might seem like an easier start, but I think you=
 technically have to solve all of the same problems anyway, even though tho=
se problems happen to be less-likely to come up in practice.</div><div><br>=
</div><div>Ultimately, I think that if we get size 0 types, we wouldn&#39;t=
 just special case arrays of size 0. An array is just an object and it bein=
g size 0 requires the same considerations as other types being size 0. In t=
he end, if we allow size 0 types, my personal conclusion is that:</div><div=
><br></div><div>1) It shouldn&#39;t be restricted to size 0 arrays</div><di=
v>2) Different objects of the same (empty) type can share the same address<=
/div><div>3) std::array_iterator&lt; /*array type*/ &gt; or something simil=
ar yields an appropriate iterator type for the array (isn&#39;t a pointer t=
ype when the element type is size 0)</div><div>4) [Unfortunately] for pract=
icality, user-defined types should at least initially have some kind of spe=
cifier-hint that tells the implementation that the type is allowed to be si=
ze 0 if it happens to have no members or all of the members/bases are also =
size 0. This is subtle, but implementations all of a sudden having somethin=
g like &quot;struct foo {};&quot; become size 0 overnight would never happe=
n, and the same goes for struct foo { /*empty type members*/ };). Because o=
f that, at least initially, people would have to explicitly request the abi=
lity for their type to potentially be size 0 when all other conditions allo=
w it, otherwise they wouldn&#39;t be able to take advantage of it in practi=
ce during the transition.</div></div></div></div></blockquote><div><br>I wo=
uld say that the requirement should be stronger than that. Your idea is to =
make it a hint, that implementations <i>may</i> allow the size to be 0. I s=
ay that it should be <i>enforced</i>. If you declare that a type is zero-si=
zed, then put things in it that aren&#39;t themselves zero-sized, then I wo=
uld say that your code is <i>incoherent</i> and does not deserve to compile=
.. It seems likely to me that a user who declares that a type will be zero-s=
ized, then does something that makes this impossible has made a mistake.<br=
><br>But at the same time, I do think it is important that users can make a=
 distinction between &quot;This type <i>will be</i> zero-sided&quot; and &q=
uot;If my declarations make this empty, then it should be zero-sized&quot;.=
<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote"><div></div><div>In other words:</div><di=
v><br></div><div>struct /*some specifier*/=C2=A0foo { /*potentially some da=
tamembers which may or may not be empty*/ };</div><div><br></div><div>where=
 the existence of /*some specifier*/ allows the implementation to let &quot=
;foo&quot; be size 0.</div></div></div></div></blockquote><div><br>As I&#39=
;ve refined my own stateless types idea, I came to realize something. While=
 it is useful to be able to declare that a type will be stateless, it is al=
so useful to declare that a type which was not explicitly declared stateles=
s can be <i>used</i> as a stateless subobject. That way, you don&#39;t crea=
te a rigid separation between the world of stateless things and the world o=
f non-stateless things.<br><br>If someone passes you an allocator that is a=
n empty type, but they didn&#39;t declare it stateless, that&#39;s OK: you =
can fix that at the point of use.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8a31c6b9-eba5-4e0a-9b9c-431f3a79c727%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8a31c6b9-eba5-4e0a-9b9c-431f3a79c727=
%40isocpp.org</a>.<br />

------=_Part_4243_845724229.1467944488295--

------=_Part_4242_587393052.1467944488295--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 7 Jul 2016 21:49:57 -0700
Raw View
--001a1143800cdc2f47053718883e
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Thursday, July 7, 2016 at 8:09:37 PM UTC-4, Matt Calabrese wrote:
>>
>> On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson <
>> bengt.gu...@beamways.com> wrote:
>>
>>> I have been following the recent thread about empty base optimization,
>>> or rather, the lack of empty member optimization possibility. And today I
>>> again fell in the 0 sized array trap in metaprogramming, noticing that it
>>> creates quite a few problems requiring extra coding.
>>>
>>
>> When I started working on Regular Void (p0146) I initially explored size
>> 0 types but decided to postpone the effort because it has some difficult
>> practical concerns regarding backwards compatibility. I think it might be
>> possible that we will eventually get to a point where the language allows
>> size 0 types, but it is not something that we can just start introducing
>> (arrays or otherwise) without broader considerations. If the language had
>> size 0 types to begin with then there would be no potential issues, but I
>> half-suspect that the transition to a world where size 0 types exist may be
>> more difficult than people would care to accept.
>>
>> Here's a brief summary of my current conclusions. I'd like to eventually
>> explore this again once Regular Void either goes into the language or is
>> killed.
>>
>> 1) In order for size 0 types to be useful as a means of minimizing
>> storage, we'd effectively have to change aliasing rules. No two objects of
>> the same type can occupy the same address in C++ as it currently is, which
>> user-level code can and does exploit.
>>
>
> Actually that's not quite true, and it is this exception that focused my
> stateless subobject idea (that I'm still occasionally refining). There are
> certain cases where two objects can have the same address. Namely, base
> class subobjects and their derived class. This is why [basic.lval]/10 has
> an explicit exception in the aliasing rules for types which are "similar
> to" the actual object's type.
>

That's why I say two /different/ objects of the /same/ type. EBO doesn't
cover that.

On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> I would say that the requirement should be stronger than that. Your idea
> is to make it a hint, that implementations *may* allow the size to be 0.
> I say that it should be *enforced*. If you declare that a type is
> zero-sized, then put things in it that aren't themselves zero-sized, then I
> would say that your code is *incoherent* and does not deserve to compile.
> It seems likely to me that a user who declares that a type will be
> zero-sized, then does something that makes this impossible has made a
> mistake.
>

It *must* be a hint to be useful in practice and it is not indicative of a
mistake for the use-cases where it is desired. Basically, the end goal is
that we want implementations to always prefer to make types such as "struct
foo {};" or "struct foo { /*all size 0 datamembers*/ };" as size 0. The
problem is that this wouldn't immediately happen in practice because it
would be an ABI break. In order for users to *actually* be able to take
advantage of this immediately during the transition, they'd need an
additional way to declare types that didn't exist before (hence the
specifier) -- this specifier doesn't have to even be a part of the
standard, technically, but it would be an extension that I'd expect
implementations to ultimately provide and that users would have to take
advantage of in order to actually get size 0 types in practice.

The reason I say that the specifier must only be a hint and not cause an
error if a user were to put a non-static datamember in the type that isn't
size 0 is because if it caused an error then it wouldn't help for one of
the primary use-cases, which is where datamembers have dependent types that
may or may not be size 0 (i.e. a tuple template). You want to be able to
declare something like a tuple template in such a way that its
instantiations are size 0 when all datamembers are size 0, yet still have
the same exact template definition when some of the dependent T types may
not be size 0. Applying the specifier on the template definition there
would do the trick if it really were just a hint, but if the "hint" were
actually something that caused an error if the type couldn't actually be
size 0, then the specifier wouldn't be usable there.

On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> As I've refined my own stateless types idea, I came to realize something.
> While it is useful to be able to declare that a type will be stateless, it
> is also useful to declare that a type which was not explicitly declared
> stateless can be *used* as a stateless subobject. That way, you don't
> create a rigid separation between the world of stateless things and the
> world of non-stateless things.
>
> If someone passes you an allocator that is an empty type, but they didn't
> declare it stateless, that's OK: you can fix that at the point of use.
>

I'm not sure I follow what you mean. I don't think we are drawing a
distinction between stateful and stateless things here. The idea is that an
instance of a current C++ type and a size 0 type can be worked with via a
common set of abstractions. If whatever we end up does not have such a set
of abstractions, then we've failed.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEmf_4AHm9JXdFPUBFh1SmkuNtWLy%2B4-UrOH1cnRLhMYyw%40mail.gmail.com.

--001a1143800cdc2f47053718883e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt;</span> wrote:<br><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);paddi=
ng-left:1ex"><div dir=3D"ltr">On Thursday, July 7, 2016 at 8:09:37 PM UTC-4=
, Matt Calabrese wrote:<span class=3D"gmail-"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-st=
yle:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"=
ltr"><div><div class=3D"gmail_quote">On Mon, Jul 4, 2016 at 8:15 AM, Bengt =
Gustafsson <span dir=3D"ltr">&lt;<a rel=3D"nofollow">bengt.gu...@beamways.c=
om</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-l=
eft-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>I have b=
een following the recent thread about empty base optimization, or rather, t=
he lack of empty member optimization possibility. And today I again fell in=
 the 0 sized array trap in metaprogramming, noticing that it creates quite =
a few problems requiring extra coding.</div></div></blockquote><div><br></d=
iv><div>When I started working on Regular Void (p0146) I initially explored=
 size 0 types but decided to postpone the effort because it has some diffic=
ult practical concerns regarding backwards compatibility. I think it might =
be possible that we will eventually get to a point where the language allow=
s size 0 types, but it is not something that we can just start introducing =
(arrays or otherwise) without broader considerations. If the language had s=
ize 0 types to begin with then there would be no potential issues, but I ha=
lf-suspect that the transition to a world where size 0 types exist may be m=
ore difficult than people would care to accept.</div><div><br></div><div>He=
re&#39;s a brief summary of my current conclusions. I&#39;d like to eventua=
lly explore this again once Regular Void either goes into the language or i=
s killed.</div><div><br></div><div>1) In order for size 0 types to be usefu=
l as a means of minimizing storage, we&#39;d effectively have to change ali=
asing rules. No two objects of the same type can occupy the same address in=
 C++ as it currently is, which user-level code can and does exploit.</div><=
/div></div></div></blockquote></span><div><br>Actually that&#39;s not quite=
 true, and it is this exception that focused my stateless subobject idea (t=
hat I&#39;m still occasionally refining). There are certain cases where two=
 objects can have the same address. Namely, base class subobjects and their=
 derived class. This is why [basic.lval]/10 has an explicit exception in th=
e aliasing rules for types which are &quot;similar to&quot; the actual obje=
ct&#39;s type.<br></div></div></blockquote><div><br></div><div>That&#39;s w=
hy I say two /different/ objects of the /same/ type. EBO doesn&#39;t cover =
that.</div><div><br></div><div>On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas=
=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:jmckesson@gmail.com">jmckesso=
n@gmail.com</a>&gt;</span>=C2=A0wrote:</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-styl=
e:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"lt=
r"><div>I would say that the requirement should be stronger than that. Your=
 idea is to make it a hint, that implementations <i>may</i> allow the size =
to be 0. I say that it should be <i>enforced</i>. If you declare that a typ=
e is zero-sized, then put things in it that aren&#39;t themselves zero-size=
d, then I would say that your code is <i>incoherent</i> and does not deserv=
e to compile. It seems likely to me that a user who declares that a type wi=
ll be zero-sized, then does something that makes this impossible has made a=
 mistake.<br></div></div></blockquote><div><br></div><div>It <i>must</i> be=
 a hint to be useful in practice and it is not indicative of a mistake for =
the use-cases where it is desired. Basically, the end goal is that we want =
implementations to always prefer to make types such as &quot;struct foo {};=
&quot; or &quot;struct foo { /*all size 0 datamembers*/ };&quot; as size 0.=
 The problem is that this wouldn&#39;t immediately happen in practice becau=
se it would be an ABI break. In order for users to <i>actually</i> be able =
to take advantage of this immediately during the transition, they&#39;d nee=
d an additional way to declare types that didn&#39;t exist before (hence th=
e specifier) -- this specifier doesn&#39;t have to even be a part of the st=
andard, technically, but it would be an extension that I&#39;d expect imple=
mentations to ultimately provide and that users would have to take advantag=
e of in order to actually get size 0 types in practice.</div><div><br></div=
><div>The reason I say that the specifier must only be a hint and not cause=
 an error if a user were to put a non-static datamember in the type that is=
n&#39;t size 0 is because if it caused an error then it wouldn&#39;t help f=
or one of the primary use-cases, which is where datamembers have dependent =
types that may or may not be size 0 (i.e. a tuple template). You want to be=
 able to declare something like a tuple template in such a way that its ins=
tantiations are size 0 when all datamembers are size 0, yet still have the =
same exact template definition when some of the dependent T types may not b=
e size 0. Applying the specifier on the template definition there would do =
the trick if it really were just a hint, but if the &quot;hint&quot; were a=
ctually something that caused an error if the type couldn&#39;t actually be=
 size 0, then the specifier wouldn&#39;t be usable there.</div><div><br></d=
iv><div>On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas=C2=A0<span dir=3D"ltr">=
&lt;<a href=3D"mailto:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt;</spa=
n>=C2=A0wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-=
color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>As I&#39;ve =
refined my own stateless types idea, I came to realize something. While it =
is useful to be able to declare that a type will be stateless, it is also u=
seful to declare that a type which was not explicitly declared stateless ca=
n be <i>used</i> as a stateless subobject. That way, you don&#39;t create a=
 rigid separation between the world of stateless things and the world of no=
n-stateless things.<br><br>If someone passes you an allocator that is an em=
pty type, but they didn&#39;t declare it stateless, that&#39;s OK: you can =
fix that at the point of use.</div></div></blockquote></div><br></div><div =
class=3D"gmail_extra">I&#39;m not sure I follow what you mean. I don&#39;t =
think we are drawing a distinction between stateful and stateless things he=
re. The idea is that an instance of a current C++ type and a size 0 type ca=
n be worked with via a common set of abstractions. If whatever we end up do=
es not have such a set of abstractions, then we&#39;ve failed.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEmf_4AHm9JXdFPUBFh1SmkuNtWLy%2B=
4-UrOH1cnRLhMYyw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEmf_4AHm9=
JXdFPUBFh1SmkuNtWLy%2B4-UrOH1cnRLhMYyw%40mail.gmail.com</a>.<br />

--001a1143800cdc2f47053718883e--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 8 Jul 2016 06:22:20 -0700 (PDT)
Raw View
------=_Part_1808_155930800.1467984140157
Content-Type: multipart/alternative;
 boundary="----=_Part_1809_1629815349.1467984140158"

------=_Part_1809_1629815349.1467984140158
Content-Type: text/plain; charset=UTF-8

On Friday, July 8, 2016 at 12:50:00 AM UTC-4, Matt Calabrese wrote:
>
> On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Thursday, July 7, 2016 at 8:09:37 PM UTC-4, Matt Calabrese wrote:
>>>
>>> On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson <
>>> bengt.gu...@beamways.com> wrote:
>>>
>>>> I have been following the recent thread about empty base optimization,
>>>> or rather, the lack of empty member optimization possibility. And today I
>>>> again fell in the 0 sized array trap in metaprogramming, noticing that it
>>>> creates quite a few problems requiring extra coding.
>>>>
>>>
>>> When I started working on Regular Void (p0146) I initially explored size
>>> 0 types but decided to postpone the effort because it has some difficult
>>> practical concerns regarding backwards compatibility. I think it might be
>>> possible that we will eventually get to a point where the language allows
>>> size 0 types, but it is not something that we can just start introducing
>>> (arrays or otherwise) without broader considerations. If the language had
>>> size 0 types to begin with then there would be no potential issues, but I
>>> half-suspect that the transition to a world where size 0 types exist may be
>>> more difficult than people would care to accept.
>>>
>>> Here's a brief summary of my current conclusions. I'd like to eventually
>>> explore this again once Regular Void either goes into the language or is
>>> killed.
>>>
>>> 1) In order for size 0 types to be useful as a means of minimizing
>>> storage, we'd effectively have to change aliasing rules. No two objects of
>>> the same type can occupy the same address in C++ as it currently is, which
>>> user-level code can and does exploit.
>>>
>>
>> Actually that's not quite true, and it is this exception that focused my
>> stateless subobject idea (that I'm still occasionally refining). There are
>> certain cases where two objects can have the same address. Namely, base
>> class subobjects and their derived class. This is why [basic.lval]/10 has
>> an explicit exception in the aliasing rules for types which are "similar
>> to" the actual object's type.
>>
>
> That's why I say two /different/ objects of the /same/ type. EBO doesn't
> cover that.
>

And my point is how you define "different". We could say that stateless
subobjects are not different objects from *any* other object. Which makes
sense, as they are stateless and therefore have no value representation.

On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmck...@gmail.com <javascript:>
> > wrote:
>
>> I would say that the requirement should be stronger than that. Your idea
>> is to make it a hint, that implementations *may* allow the size to be 0.
>> I say that it should be *enforced*. If you declare that a type is
>> zero-sized, then put things in it that aren't themselves zero-sized, then I
>> would say that your code is *incoherent* and does not deserve to
>> compile. It seems likely to me that a user who declares that a type will be
>> zero-sized, then does something that makes this impossible has made a
>> mistake.
>>
>
> It *must* be a hint to be useful in practice and it is not indicative of
> a mistake for the use-cases where it is desired. Basically, the end goal is
> that we want implementations to always prefer to make types such as "struct
> foo {};" or "struct foo { /*all size 0 datamembers*/ };" as size 0. The
> problem is that this wouldn't immediately happen in practice because it
> would be an ABI break. In order for users to *actually* be able to take
> advantage of this immediately during the transition, they'd need an
> additional way to declare types that didn't exist before (hence the
> specifier) -- this specifier doesn't have to even be a part of the
> standard, technically, but it would be an extension that I'd expect
> implementations to ultimately provide and that users would have to take
> advantage of in order to actually get size 0 types in practice.
>
> The reason I say that the specifier must only be a hint and not cause an
> error if a user were to put a non-static datamember in the type that isn't
> size 0 is because if it caused an error then it wouldn't help for one of
> the primary use-cases, which is where datamembers have dependent types that
> may or may not be size 0 (i.e. a tuple template). You want to be able to
> declare something like a tuple template in such a way that its
> instantiations are size 0 when all datamembers are size 0, yet still have
> the same exact template definition when some of the dependent T types may
> not be size 0. Applying the specifier on the template definition there
> would do the trick if it really were just a hint, but if the "hint" were
> actually something that caused an error if the type couldn't actually be
> size 0, then the specifier wouldn't be usable there.
>

That's why I said:

But at the same time, I do think it is important that users can make a
> distinction between "This type *will be* zero-sided" and "If my
> declarations make this empty, then it should be zero-sized".
>

For that tuple case, you need the latter. But for other cases, people need
the former.


>
> On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> As I've refined my own stateless types idea, I came to realize something.
>> While it is useful to be able to declare that a type will be stateless, it
>> is also useful to declare that a type which was not explicitly declared
>> stateless can be *used* as a stateless subobject. That way, you don't
>> create a rigid separation between the world of stateless things and the
>> world of non-stateless things.
>>
>> If someone passes you an allocator that is an empty type, but they didn't
>> declare it stateless, that's OK: you can fix that at the point of use.
>>
>
> I'm not sure I follow what you mean. I don't think we are drawing a
> distinction between stateful and stateless things here. The idea is that an
> instance of a current C++ type and a size 0 type can be worked with via a
> common set of abstractions. If whatever we end up does not have such a set
> of abstractions, then we've failed.
>

My point is that whatever "common set of abstractions" you work out, this
class definition must not be zero-sized:

struct empty{};

The reason being that it isn't zero-sized today, and making it zero-sized
would represent a breaking, non-backwards-compatible change not only to
itself but to every subobject it is used in. That's not acceptable for
obvious reasons.

`std::allocator` is an empty class (probably). As such, if I want to make a
member variable of that type which takes up no space, how do I do that? If
you rely only on the type's definition to explicitly say that it is
zero-sized, you can't. Thus, you divide the world into two divisions: code
written after the standard changed, and code written before it changed.

Yet logically, any empty class ought to be able to be used in a
zero-sized/stateless/whatever-you-call-it way, when declared as a
subobjbect. Thus, any solution to this problem ought needs to also be able
to be employed on a per-use basis.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f3b99829-432a-47a4-b227-48e70cb18da5%40isocpp.org.

------=_Part_1809_1629815349.1467984140158
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, July 8, 2016 at 12:50:00 AM UTC-4, Matt Calabre=
se wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote">On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <sp=
an dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated=
-mailto=3D"02-rY8ZRCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;">jmck...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr">On Thursday, July 7, 2016 at 8:09:37 PM UTC-4, Matt Calabr=
ese wrote:<span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_=
quote">On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson <span dir=3D"ltr">&=
lt;<a rel=3D"nofollow">bengt.gu...@beamways.com</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);pad=
ding-left:1ex"><div dir=3D"ltr"><div>I have been following the recent threa=
d about empty base optimization, or rather, the lack of empty member optimi=
zation possibility. And today I again fell in the 0 sized array trap in met=
aprogramming, noticing that it creates quite a few problems requiring extra=
 coding.</div></div></blockquote><div><br></div><div>When I started working=
 on Regular Void (p0146) I initially explored size 0 types but decided to p=
ostpone the effort because it has some difficult practical concerns regardi=
ng backwards compatibility. I think it might be possible that we will event=
ually get to a point where the language allows size 0 types, but it is not =
something that we can just start introducing (arrays or otherwise) without =
broader considerations. If the language had size 0 types to begin with then=
 there would be no potential issues, but I half-suspect that the transition=
 to a world where size 0 types exist may be more difficult than people woul=
d care to accept.</div><div><br></div><div>Here&#39;s a brief summary of my=
 current conclusions. I&#39;d like to eventually explore this again once Re=
gular Void either goes into the language or is killed.</div><div><br></div>=
<div>1) In order for size 0 types to be useful as a means of minimizing sto=
rage, we&#39;d effectively have to change aliasing rules. No two objects of=
 the same type can occupy the same address in C++ as it currently is, which=
 user-level code can and does exploit.</div></div></div></div></blockquote>=
</span><div><br>Actually that&#39;s not quite true, and it is this exceptio=
n that focused my stateless subobject idea (that I&#39;m still occasionally=
 refining). There are certain cases where two objects can have the same add=
ress. Namely, base class subobjects and their derived class. This is why [b=
asic.lval]/10 has an explicit exception in the aliasing rules for types whi=
ch are &quot;similar to&quot; the actual object&#39;s type.<br></div></div>=
</blockquote><div><br></div><div>That&#39;s why I say two /different/ objec=
ts of the /same/ type. EBO doesn&#39;t cover that.</div></div></div></div><=
/blockquote><div><br>And my point is how you define &quot;different&quot;. =
We could say that stateless subobjects are not different objects from <i>an=
y</i> other object. Which makes sense, as they are stateless and therefore =
have no value representation.<br><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><d=
iv>On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas=C2=A0<span dir=3D"ltr">&lt;<=
a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"02-rY8ZRC=
QAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;retu=
rn true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck..=
..@gmail.com</a>&gt;</span>=C2=A0<wbr>wrote:</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left=
-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div>I would say that the requirement should be stronger than that=
.. Your idea is to make it a hint, that implementations <i>may</i> allow the=
 size to be 0. I say that it should be <i>enforced</i>. If you declare that=
 a type is zero-sized, then put things in it that aren&#39;t themselves zer=
o-sized, then I would say that your code is <i>incoherent</i> and does not =
deserve to compile. It seems likely to me that a user who declares that a t=
ype will be zero-sized, then does something that makes this impossible has =
made a mistake.<br></div></div></blockquote><div><br></div><div>It <i>must<=
/i> be a hint to be useful in practice and it is not indicative of a mistak=
e for the use-cases where it is desired. Basically, the end goal is that we=
 want implementations to always prefer to make types such as &quot;struct f=
oo {};&quot; or &quot;struct foo { /*all size 0 datamembers*/ };&quot; as s=
ize 0. The problem is that this wouldn&#39;t immediately happen in practice=
 because it would be an ABI break. In order for users to <i>actually</i> be=
 able to take advantage of this immediately during the transition, they&#39=
;d need an additional way to declare types that didn&#39;t exist before (he=
nce the specifier) -- this specifier doesn&#39;t have to even be a part of =
the standard, technically, but it would be an extension that I&#39;d expect=
 implementations to ultimately provide and that users would have to take ad=
vantage of in order to actually get size 0 types in practice.</div><div><br=
></div><div>The reason I say that the specifier must only be a hint and not=
 cause an error if a user were to put a non-static datamember in the type t=
hat isn&#39;t size 0 is because if it caused an error then it wouldn&#39;t =
help for one of the primary use-cases, which is where datamembers have depe=
ndent types that may or may not be size 0 (i.e. a tuple template). You want=
 to be able to declare something like a tuple template in such a way that i=
ts instantiations are size 0 when all datamembers are size 0, yet still hav=
e the same exact template definition when some of the dependent T types may=
 not be size 0. Applying the specifier on the template definition there wou=
ld do the trick if it really were just a hint, but if the &quot;hint&quot; =
were actually something that caused an error if the type couldn&#39;t actua=
lly be size 0, then the specifier wouldn&#39;t be usable there.</div></div>=
</div></div></blockquote><div><br>That&#39;s why I said:<br><br><blockquote=
 style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 2=
04); padding-left: 1ex;" class=3D"gmail_quote">But at the same time, I do t=
hink it is important that users can make a distinction between &quot;This t=
ype <i>will be</i> zero-sided&quot; and &quot;If my declarations make this =
empty, then it should be zero-sized&quot;.<br></blockquote><br>For that tup=
le case, you need the latter. But for other cases, people need the former.<=
br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div><div class=3D"gmail_quote"><div><br></div><div>On Thu, Jul 7, 2016 a=
t 7:21 PM, Nicol Bolas=C2=A0<span dir=3D"ltr">&lt;<a href=3D"javascript:" t=
arget=3D"_blank" gdf-obfuscated-mailto=3D"02-rY8ZRCQAJ" rel=3D"nofollow" on=
mousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"thi=
s.href=3D&#39;javascript:&#39;;return true;">jmck...@gmail.com</a>&gt;</spa=
n>=C2=A0<wbr>wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-=
left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>As I&#3=
9;ve refined my own stateless types idea, I came to realize something. Whil=
e it is useful to be able to declare that a type will be stateless, it is a=
lso useful to declare that a type which was not explicitly declared statele=
ss can be <i>used</i> as a stateless subobject. That way, you don&#39;t cre=
ate a rigid separation between the world of stateless things and the world =
of non-stateless things.<br><br>If someone passes you an allocator that is =
an empty type, but they didn&#39;t declare it stateless, that&#39;s OK: you=
 can fix that at the point of use.</div></div></blockquote></div><br></div>=
<div>I&#39;m not sure I follow what you mean. I don&#39;t think we are draw=
ing a distinction between stateful and stateless things here. The idea is t=
hat an instance of a current C++ type and a size 0 type can be worked with =
via a common set of abstractions. If whatever we end up does not have such =
a set of abstractions, then we&#39;ve failed.</div></div></blockquote><div>=
<br>My point is that whatever &quot;common set of abstractions&quot; you wo=
rk out, this class definition must not be zero-sized:<br><br><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break=
-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> empty</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{};</span></div></code></div><br=
>The reason being that it isn&#39;t zero-sized today, and making it zero-si=
zed would represent a breaking, non-backwards-compatible change not only to=
 itself but to every subobject it is used in. That&#39;s not acceptable for=
 obvious reasons.<br><br>`std::allocator` is an empty class (probably). As =
such, if I want to make a member variable of that type which takes up no sp=
ace, how do I do that? If you rely only on the type&#39;s definition to exp=
licitly say that it is zero-sized, you can&#39;t. Thus, you divide the worl=
d into two divisions: code written after the standard changed, and code wri=
tten before it changed.<br><br>Yet logically, any empty class ought to be a=
ble to be used in a zero-sized/stateless/whatever-you-call-it way, when dec=
lared as a subobjbect. Thus, any solution to this problem ought needs to al=
so be able to be employed on a per-use basis.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f3b99829-432a-47a4-b227-48e70cb18da5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f3b99829-432a-47a4-b227-48e70cb18da5=
%40isocpp.org</a>.<br />

------=_Part_1809_1629815349.1467984140158--

------=_Part_1808_155930800.1467984140157--

.


Author: Peter Koch Larsen <peter.koch.larsen@gmail.com>
Date: Fri, 8 Jul 2016 17:58:29 +0200
Raw View
Sean Parent in his key-note talk at cppnow proposed making void a
regular, empty type. At the same time he proposed that when inheriting
from void, you would have a truly empty type. I like that idea.

struct empty{};  // Not really empty.
struct truly_empty: void {};  //This one is!

static assert(sizeof(empty) == 1);
static assert(sizeof(truly_empty) == 0);

/Peter

On Fri, Jul 8, 2016 at 3:22 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Friday, July 8, 2016 at 12:50:00 AM UTC-4, Matt Calabrese wrote:
>>
>> On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>> On Thursday, July 7, 2016 at 8:09:37 PM UTC-4, Matt Calabrese wrote:
>>>>
>>>> On Mon, Jul 4, 2016 at 8:15 AM, Bengt Gustafsson
>>>> <bengt.gu...@beamways.com> wrote:
>>>>>
>>>>> I have been following the recent thread about empty base optimization,
>>>>> or rather, the lack of empty member optimization possibility. And today I
>>>>> again fell in the 0 sized array trap in metaprogramming, noticing that it
>>>>> creates quite a few problems requiring extra coding.
>>>>
>>>>
>>>> When I started working on Regular Void (p0146) I initially explored size
>>>> 0 types but decided to postpone the effort because it has some difficult
>>>> practical concerns regarding backwards compatibility. I think it might be
>>>> possible that we will eventually get to a point where the language allows
>>>> size 0 types, but it is not something that we can just start introducing
>>>> (arrays or otherwise) without broader considerations. If the language had
>>>> size 0 types to begin with then there would be no potential issues, but I
>>>> half-suspect that the transition to a world where size 0 types exist may be
>>>> more difficult than people would care to accept.
>>>>
>>>> Here's a brief summary of my current conclusions. I'd like to eventually
>>>> explore this again once Regular Void either goes into the language or is
>>>> killed.
>>>>
>>>> 1) In order for size 0 types to be useful as a means of minimizing
>>>> storage, we'd effectively have to change aliasing rules. No two objects of
>>>> the same type can occupy the same address in C++ as it currently is, which
>>>> user-level code can and does exploit.
>>>
>>>
>>> Actually that's not quite true, and it is this exception that focused my
>>> stateless subobject idea (that I'm still occasionally refining). There are
>>> certain cases where two objects can have the same address. Namely, base
>>> class subobjects and their derived class. This is why [basic.lval]/10 has an
>>> explicit exception in the aliasing rules for types which are "similar to"
>>> the actual object's type.
>>
>>
>> That's why I say two /different/ objects of the /same/ type. EBO doesn't
>> cover that.
>
>
> And my point is how you define "different". We could say that stateless
> subobjects are not different objects from any other object. Which makes
> sense, as they are stateless and therefore have no value representation.
>
>> On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>> I would say that the requirement should be stronger than that. Your idea
>>> is to make it a hint, that implementations may allow the size to be 0. I say
>>> that it should be enforced. If you declare that a type is zero-sized, then
>>> put things in it that aren't themselves zero-sized, then I would say that
>>> your code is incoherent and does not deserve to compile. It seems likely to
>>> me that a user who declares that a type will be zero-sized, then does
>>> something that makes this impossible has made a mistake.
>>
>>
>> It must be a hint to be useful in practice and it is not indicative of a
>> mistake for the use-cases where it is desired. Basically, the end goal is
>> that we want implementations to always prefer to make types such as "struct
>> foo {};" or "struct foo { /*all size 0 datamembers*/ };" as size 0. The
>> problem is that this wouldn't immediately happen in practice because it
>> would be an ABI break. In order for users to actually be able to take
>> advantage of this immediately during the transition, they'd need an
>> additional way to declare types that didn't exist before (hence the
>> specifier) -- this specifier doesn't have to even be a part of the standard,
>> technically, but it would be an extension that I'd expect implementations to
>> ultimately provide and that users would have to take advantage of in order
>> to actually get size 0 types in practice.
>>
>> The reason I say that the specifier must only be a hint and not cause an
>> error if a user were to put a non-static datamember in the type that isn't
>> size 0 is because if it caused an error then it wouldn't help for one of the
>> primary use-cases, which is where datamembers have dependent types that may
>> or may not be size 0 (i.e. a tuple template). You want to be able to declare
>> something like a tuple template in such a way that its instantiations are
>> size 0 when all datamembers are size 0, yet still have the same exact
>> template definition when some of the dependent T types may not be size 0.
>> Applying the specifier on the template definition there would do the trick
>> if it really were just a hint, but if the "hint" were actually something
>> that caused an error if the type couldn't actually be size 0, then the
>> specifier wouldn't be usable there.
>
>
> That's why I said:
>
>> But at the same time, I do think it is important that users can make a
>> distinction between "This type will be zero-sided" and "If my declarations
>> make this empty, then it should be zero-sized".
>
>
> For that tuple case, you need the latter. But for other cases, people need
> the former.
>
>>
>>
>> On Thu, Jul 7, 2016 at 7:21 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>> As I've refined my own stateless types idea, I came to realize something.
>>> While it is useful to be able to declare that a type will be stateless, it
>>> is also useful to declare that a type which was not explicitly declared
>>> stateless can be used as a stateless subobject. That way, you don't create a
>>> rigid separation between the world of stateless things and the world of
>>> non-stateless things.
>>>
>>> If someone passes you an allocator that is an empty type, but they didn't
>>> declare it stateless, that's OK: you can fix that at the point of use.
>>
>>
>> I'm not sure I follow what you mean. I don't think we are drawing a
>> distinction between stateful and stateless things here. The idea is that an
>> instance of a current C++ type and a size 0 type can be worked with via a
>> common set of abstractions. If whatever we end up does not have such a set
>> of abstractions, then we've failed.
>
>
> My point is that whatever "common set of abstractions" you work out, this
> class definition must not be zero-sized:
>
> struct empty{};
>
> The reason being that it isn't zero-sized today, and making it zero-sized
> would represent a breaking, non-backwards-compatible change not only to
> itself but to every subobject it is used in. That's not acceptable for
> obvious reasons.
>
> `std::allocator` is an empty class (probably). As such, if I want to make a
> member variable of that type which takes up no space, how do I do that? If
> you rely only on the type's definition to explicitly say that it is
> zero-sized, you can't. Thus, you divide the world into two divisions: code
> written after the standard changed, and code written before it changed.
>
> Yet logically, any empty class ought to be able to be used in a
> zero-sized/stateless/whatever-you-call-it way, when declared as a
> subobjbect. Thus, any solution to this problem ought needs to also be able
> to be employed on a per-use basis.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f3b99829-432a-47a4-b227-48e70cb18da5%40isocpp.org.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANPtknwMe0KS%3DOqrkbUWwRwWQX2Vu90XeXc8XU3oLFPFiunQ%3DQ%40mail.gmail.com.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 9 Jul 2016 01:06:43 -0700 (PDT)
Raw View
------=_Part_5613_1410626931.1468051603299
Content-Type: multipart/alternative;
 boundary="----=_Part_5614_1759838631.1468051603307"

------=_Part_5614_1759838631.1468051603307
Content-Type: text/plain; charset=UTF-8

Avoiding these issues with syntax and semantics of declaring types that are
zero sized was one of my original motivations for trying the idea of using
a zero sized array of any type to get a zero sized variable of an empty
type.

As zero sized arrays are not allowed currently there is an open space for
defining the exact semantics. As for Matt's original complaints these are
valid for other ways to declare zero sized objects but not for zero sized
arrays as they have never been allowed before. For instance it is obvious
what a for loop over a zero sized array is to do: nothing. It is also easy
to define what the size of an array of zero sized arrays is to mean: still
an array of a total of zero elements, which follows the logic for all other
sizes: multiply all dimension's sizes to get the total size. Furthermore
the byte size of zero is consistent with the current way to calculate the
byte size of an array variable: multply the align-adjusted element size
with the element count of the array.

Zero sized arrays as such are also useful in the context of template code,
where 0 may be a valid template parameter to instantiate with (such as for
sentinels).


On the other hand the SFINAE example presented:

>
> One of the ways the SFINAE-rule is actually used:
>   void foo(char (*)[...evaluates to 0 or >0...] =0)
>   void foo(...)   // other overloads
> which is (currently) equivalent to (e.g.)
>   std::disable_if<...evaluates to false/true...>::type foo();
>   // other overloads
> but would not, if zero-sized arrays are allowed (developers would have to
> replace "[value]" with "[2*(value)-1]" to get a negative-sized array for
> "false" to still fail SFINAE).
>

This seems to be something that people actually could have used before
enable_if was defined.  Don't know if this is common enough to preclude
introducing zero sized arrays, what do you think?


--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ac3527d9-086c-41c7-8674-9079a4c8821e%40isocpp.org.

------=_Part_5614_1759838631.1468051603307
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Avoiding these issues with syntax and semantics of declari=
ng types that are zero sized was one of my original motivations for trying =
the idea of using a zero sized array of any type to get a zero sized variab=
le of an empty type.=C2=A0<div><br></div><div>As zero sized arrays are not =
allowed currently there is an open space for defining the exact semantics. =
As for Matt&#39;s original complaints these are valid for other ways to dec=
lare zero sized objects but not for zero sized arrays as they have never be=
en allowed before. For instance it is obvious what a for loop over a zero s=
ized array is to do: nothing. It is also easy to define what the size of an=
 array of zero sized arrays is to mean: still an array of a total of zero e=
lements, which follows the logic for all other sizes: multiply all dimensio=
n&#39;s sizes to get the total size. Furthermore the byte size of zero is c=
onsistent with the current way to calculate the byte size of an array varia=
ble: multply the align-adjusted element size with the element count of the =
array.</div><div><br></div><div>Zero sized arrays as such are also useful i=
n the context of template code, where 0 may be a valid template parameter t=
o instantiate with (such as for sentinels).</div><div><br><div><br></div><d=
iv>On the other hand the SFINAE example presented:</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;"><br>One of the ways the SFINAE-rul=
e is actually used:<br>=C2=A0 void foo(char (*)[...evaluates to 0 or &gt;0.=
...] =3D0)<br>=C2=A0 void foo(...) =C2=A0 // other overloads<br>which is (cu=
rrently) equivalent to (e.g.)<br>=C2=A0 std::disable_if&lt;...evaluates to =
false/true...&gt;::type foo();<br>=C2=A0 // other overloads<br>but would no=
t, if zero-sized arrays are allowed (developers would have to replace &quot=
;[value]&quot; with &quot;[2*(value)-1]&quot; to get a negative-sized array=
 for &quot;false&quot; to still fail SFINAE).<br>=C2=A0=C2=A0</blockquote><=
div>This seems to be something that people actually could have used before =
enable_if was defined. =C2=A0Don&#39;t know if this is common enough to pre=
clude introducing zero sized arrays, what do you think?</div></div><div><br=
></div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ac3527d9-086c-41c7-8674-9079a4c8821e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ac3527d9-086c-41c7-8674-9079a4c8821e=
%40isocpp.org</a>.<br />

------=_Part_5614_1759838631.1468051603307--

------=_Part_5613_1410626931.1468051603299--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 9 Jul 2016 08:33:53 -0700 (PDT)
Raw View
------=_Part_6_507880234.1468078433505
Content-Type: multipart/alternative;
 boundary="----=_Part_7_1787231895.1468078433505"

------=_Part_7_1787231895.1468078433505
Content-Type: text/plain; charset=UTF-8



On Friday, July 8, 2016 at 11:58:32 AM UTC-4, Peter Koch Larsen wrote:
>
> Sean Parent in his key-note talk at cppnow proposed making void a
> regular, empty type. At the same time he proposed that when inheriting
> from void, you would have a truly empty type. I like that idea.
>
> struct empty{};  // Not really empty.
> struct truly_empty: void {};  //This one is!
>
> static assert(sizeof(empty) == 1);
> static assert(sizeof(truly_empty) == 0);
>
> /Peter
>

Right, but how does that resolve the problem in question? Namely, this:

template<typename Alloc>
struct Me
{
  Alloc mine;
};

The point is that we want `mine` to not take up space if `Alloc` is an
empty type. Your way puts the onus on the user to declare their `Alloc` as
being derived from `void`. That's bad, because we cannot suddenly declare
that `std::allocator` derives from `void`. That would break code.

Which means people would *still* have to use the EBO hack:

template<typename Alloc>
struct Me : public Alloc
{};

You've solved a particular problem, but you haven't solved *this* problem.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e4f3c2e1-b89c-4390-88dd-87a615b3aa32%40isocpp.org.

------=_Part_7_1787231895.1468078433505
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, July 8, 2016 at 11:58:32 AM UTC-4, Pete=
r Koch Larsen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Sean Paren=
t in his key-note talk at cppnow proposed making void a
<br>regular, empty type. At the same time he proposed that when inheriting
<br>from void, you would have a truly empty type. I like that idea.
<br>
<br>struct empty{}; =C2=A0// Not really empty.
<br>struct truly_empty: void {}; =C2=A0//This one is!
<br>
<br>static assert(sizeof(empty) =3D=3D 1);
<br>static assert(sizeof(truly_empty) =3D=3D 0);
<br>
<br>/Peter<br></blockquote><div><br>Right, but how does that resolve the pr=
oblem in question? Namely, this:<br><br><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Alloc</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">st=
ruct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Me</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">Alloc</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> mine</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">};</span></div></code></div><br>The point is that we want `mi=
ne` to not take up space if `Alloc` is an empty type. Your way puts the onu=
s on the user to declare their `Alloc` as being derived from `void`. That&#=
39;s bad, because we cannot suddenly declare that `std::allocator` derives =
from `void`. That would break code.<br><br>Which means people would <i>stil=
l</i> have to use the EBO hack:<br><br><div class=3D"prettyprint" style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">template</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pr=
ettify">Alloc</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #606;" class=3D"styled-by-prettify">Me</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">public</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Alloc</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{};<=
/span></div></code></div><br>You&#39;ve solved a particular problem, but yo=
u haven&#39;t solved <i>this</i> problem.</div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e4f3c2e1-b89c-4390-88dd-87a615b3aa32%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e4f3c2e1-b89c-4390-88dd-87a615b3aa32=
%40isocpp.org</a>.<br />

------=_Part_7_1787231895.1468078433505--

------=_Part_6_507880234.1468078433505--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 9 Jul 2016 09:47:44 -0700 (PDT)
Raw View
------=_Part_12_528473856.1468082864158
Content-Type: multipart/alternative;
 boundary="----=_Part_13_885090574.1468082864159"

------=_Part_13_885090574.1468082864159
Content-Type: text/plain; charset=UTF-8

On Saturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt Gustafsson wrote:
>
> Avoiding these issues with syntax and semantics of declaring types that
> are zero sized was one of my original motivations for trying the idea of
> using a zero sized array of any type to get a zero sized variable of an
> empty type.
>

Syntax is irrelevant; *semantics* is the main problem. At present, the
semantics of your proposal are quite unclear. You say that zero-sized
arrays are a thing, but you don't tell us how they really *behave*. Or
rather, your explanation of their behavior is contradictory, broken, or
just confused.

You still haven't answered one of the most important questions. Namely,
what does this do:

int i[0];
int *j = i;
*j = 54;

Is that legal? If that's not legal, then how could *this* be legal:

Type t[0];
Type *j = t;
j->SomeMemberFunction();

And if that isn't legal, how could you actually do anything with a
zero-sized array? How do you access non-static members of such objects? How
do you call member functions? And so forth.

The thing people forget about zero-size arrays in C is that they're...
empty. If you have a zero-sized array of structs, you can't access members
of them. And the whole point of this exercise is to have an object that
takes up no space, but we can *still access*.

Also, you never answered my question from earlier in the thread: where does
`j` point to? I've already proven that your desired answer (a pointer past
the previous member) is non-functional. Such a pointer can alias with other
objects if it falls outside the valid range of the type. And such aliasing
is forbidden.

You say that you can give zero-sized arrays whatever semantics you want.
But you don't have a coherent, *detailed* explanation for what those
semantics are.


> As zero sized arrays are not allowed currently there is an open space for
> defining the exact semantics. As for Matt's original complaints these are
> valid for other ways to declare zero sized objects but not for zero sized
> arrays as they have never been allowed before. For instance it is obvious
> what a for loop over a zero sized array is to do: nothing.
>

No. No, it isn't.

Take the following code, for some object `i`:

auto start = std::addressof(i);
auto end = ++start;
for(; start < end; ++start)
{...}

Now, this code is perfectly, 100% valid for any complete object `i`. Even
if `i` were an array, the standard guarantees that this is legal. Not only
is it legal for any complete object `i`, it has the same behavior: it will
execute the loop exactly once. Even if `i` is an array, it will execute
that loop once.

So if `i` were declared as a zero-sized array, some rule of C++ must either
prevent this code from being legal or make `++start` not change the address
of the pointer (which now means that the loop executes 0 times).

So, what is the rule you propose to change that does one of these two
things? Are you going to declare that if you have a pointer to an object
which is in a zero-sized array, it is undefined behavior to perform pointer
arithmetic on it? Are you going to declare that taking the address of a
zero-sized array is il-formed entirely?

What is your solution to this problem?

It is also easy to define what the size of an array of zero sized arrays is
> to mean: still an array of a total of zero elements, which follows the
> logic for all other sizes: multiply all dimension's sizes to get the total
> size. Furthermore the byte size of zero is consistent with the current way
> to calculate the byte size of an array variable: multply the align-adjusted
> element size with the element count of the array.
>

OK, so if I have this:

T t[20];

int i = 0;
for(T &tref : t)
{
  ++i;
}

Now, given this as a definition of `T`:

using T = int[0];

Will `i` be 20 or 0 after executing the above code? Because for any
non-zero-sized type `T`, it's guaranteed to be 20. Whereas `begin` and
`end` for an array of zero-sized elements must be the same pointer.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3a25f981-d5bd-4f0e-afe4-0e917d87ecb6%40isocpp.org.

------=_Part_13_885090574.1468082864159
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt Gusta=
fsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">A=
voiding these issues with syntax and semantics of declaring types that are =
zero sized was one of my original motivations for trying the idea of using =
a zero sized array of any type to get a zero sized variable of an empty typ=
e.</div></blockquote><div><br>Syntax is irrelevant; <i>semantics</i> is the=
 main problem. At present, the semantics of your proposal are quite unclear=
.. You say that zero-sized arrays are a thing, but you don&#39;t tell us how=
 they really <i>behave</i>. Or rather, your explanation of their behavior i=
s contradictory, broken, or just confused.<br><br>You still haven&#39;t ans=
wered one of the most important questions. Namely, what does this do:<br><b=
r><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">[</span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">];</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">j </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">j </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">=
54</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span>=
</div></code></div><br>Is that legal? If that&#39;s not legal, then how cou=
ld <i>this</i> be legal:<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #606;" class=3D"=
styled-by-prettify">Type</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> t</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">[</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">];</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Type</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">j </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> t</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>j</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</span>=
<span style=3D"color: #606;" class=3D"styled-by-prettify">SomeMemberFunctio=
n</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span=
></div></code></div><br>And if that isn&#39;t legal, how could you actually=
 do anything with a zero-sized array? How do you access non-static members =
of such objects? How do you call member functions? And so forth.<br><br>The=
 thing people forget about zero-size arrays in C is that they&#39;re... emp=
ty. If you have a zero-sized array of structs, you can&#39;t access members=
 of them. And the whole point of this exercise is to have an object that ta=
kes up no space, but we can <i>still access</i>.<br><br>Also, you never ans=
wered my question from earlier in the thread: where does `j` point to? I&#3=
9;ve already proven that your desired answer (a pointer past the previous m=
ember) is non-functional. Such a pointer can alias with other objects if it=
 falls outside the valid range of the type. And such aliasing is forbidden.=
<br><br>You say that you can give zero-sized arrays whatever semantics you =
want. But you don&#39;t have a coherent, <i>detailed</i> explanation for wh=
at those semantics are.<br>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div></div><div>As zero sized arrays are not allo=
wed currently there is an open space for defining the exact semantics. As f=
or Matt&#39;s original complaints these are valid for other ways to declare=
 zero sized objects but not for zero sized arrays as they have never been a=
llowed before. For instance it is obvious what a for loop over a zero sized=
 array is to do: nothing.</div></div></blockquote><div><br>No. No, it isn&#=
39;t.<br><br>Take the following code, for some object `i`:<br><br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> start </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">addressof</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">i</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">end</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">++</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">start</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">for<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> start </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">end</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">++</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">start</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{...}</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div><=
/code></div><br>Now, this code is perfectly, 100% valid for any complete ob=
ject `i`. Even if `i` were an array, the standard guarantees that this is l=
egal. Not only is it legal for any complete object `i`, it has the same beh=
avior: it will execute the loop exactly once. Even if `i` is an array, it w=
ill execute that loop once.<br><br>So if `i` were declared as a zero-sized =
array, some rule of C++ must either prevent this code from being legal or m=
ake `++start` not change the address of the pointer (which now means that t=
he loop executes 0 times).<br><br>So, what is the rule you propose to chang=
e that does one of these two things? Are you going to declare that if you h=
ave a pointer to an object which is in a zero-sized array, it is undefined =
behavior to perform pointer arithmetic on it? Are you going to declare that=
 taking the address of a zero-sized array is il-formed entirely?<br><br>Wha=
t is your solution to this problem?<br><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div>It is also easy to define what the=
 size of an array of zero sized arrays is to mean: still an array of a tota=
l of zero elements, which follows the logic for all other sizes: multiply a=
ll dimension&#39;s sizes to get the total size. Furthermore the byte size o=
f zero is consistent with the current way to=20
calculate the byte size of an array variable: multply the align-adjusted
 element size with the element count of the array.</div></div></blockquote>=
<div><br>OK, so if I have this:<br><br><div class=3D"prettyprint" style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">T t</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-by=
-prettify">20</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">];</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">for</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">tref </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> t</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">++</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></=
code></div><br>Now, given this as a definition of `T`:<br><br><div class=3D=
"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: =
rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: brea=
k-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">using</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">]=
;</span></div></code></div><br>Will `i` be 20 or 0 after executing the abov=
e code? Because for any non-zero-sized type `T`, it&#39;s guaranteed to be =
20. Whereas `begin` and `end` for an array of zero-sized elements must be t=
he same pointer.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3a25f981-d5bd-4f0e-afe4-0e917d87ecb6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3a25f981-d5bd-4f0e-afe4-0e917d87ecb6=
%40isocpp.org</a>.<br />

------=_Part_13_885090574.1468082864159--

------=_Part_12_528473856.1468082864158--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 11 Jul 2016 10:34:49 -0700
Raw View
--94eb2c124170c167bd05375f91e8
Content-Type: text/plain; charset=UTF-8

On Sat, Jul 9, 2016 at 1:06 AM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> As zero sized arrays are not allowed currently there is an open space for
> defining the exact semantics. As for Matt's original complaints these are
> valid for other ways to declare zero sized objects but not for zero sized
> arrays as they have never been allowed before. For instance it is obvious
> what a for loop over a zero sized array is to do: nothing. It is also easy
> to define what the size of an array of zero sized arrays is to mean: still
> an array of a total of zero elements, which follows the logic for all other
> sizes: multiply all dimension's sizes to get the total size. Furthermore
> the byte size of zero is consistent with the current way to calculate the
> byte size of an array variable: multply the align-adjusted element size
> with the element count of the array.
>

I believe you may have missed what I was trying to get across. Things like
arrays of empty types still exist when you attempt to restrict size 0 types
to arrays. To reiterate, for example, just like other types, you can make
arrays of arrays (a multidimensional array in C++ is just an array of
arrays). Once you have arrays of size 0, you can make arrays of empty types
because you can make arrays whose element type is array of size 0. However
rare that may seem, it is the same problem that you encounter with more
general size 0 types and needs to be explicitly addressed. In other words,
while limiting things to size 0 arrays you *may* make it less common for
people to ask questions about corner cases, but those questions still need
to have answers when creating the specification. That answer should make
sense and be consistent with whatever we'd decide for further size 0 types,
so I don't think we're realistically making things easier by keeping things
restricted to size 0 arrays. Most of the harder questions still need the
same kinds of answers.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEna4K9FZvU3aUfvqtRJUO9k_y3nXHMs5gumZsNX_U_PuQ%40mail.gmail.com.

--94eb2c124170c167bd05375f91e8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
at, Jul 9, 2016 at 1:06 AM, Bengt Gustafsson <span dir=3D"ltr">&lt;<a href=
=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafsso=
n@beamways.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div>As zero sized arrays are not allowed currently there is a=
n open space for defining the exact semantics. As for Matt&#39;s original c=
omplaints these are valid for other ways to declare zero sized objects but =
not for zero sized arrays as they have never been allowed before. For insta=
nce it is obvious what a for loop over a zero sized array is to do: nothing=
.. It is also easy to define what the size of an array of zero sized arrays =
is to mean: still an array of a total of zero elements, which follows the l=
ogic for all other sizes: multiply all dimension&#39;s sizes to get the tot=
al size. Furthermore the byte size of zero is consistent with the current w=
ay to calculate the byte size of an array variable: multply the align-adjus=
ted element size with the element count of the array.</div></div></blockquo=
te><div><br></div><div>I believe you may have missed what I was trying to g=
et across. Things like arrays of empty types still exist when you attempt t=
o restrict size 0 types to arrays. To reiterate, for example, just like oth=
er types, you can make arrays of arrays (a multidimensional array in C++ is=
 just an array of arrays). Once you have arrays of size 0, you can make arr=
ays of empty types because you can make arrays whose element type is array =
of size 0. However rare that may seem, it is the same problem that you enco=
unter with more general size 0 types and needs to be explicitly addressed. =
In other words, while limiting things to size 0 arrays you <i>may</i> make =
it less common for people to ask questions about corner cases, but those qu=
estions still need to have answers when creating the specification. That an=
swer should make sense and be consistent with whatever we&#39;d decide for =
further size 0 types, so I don&#39;t think we&#39;re realistically making t=
hings easier by keeping things restricted to size 0 arrays. Most of the har=
der questions still need the same kinds of answers.</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEna4K9FZvU3aUfvqtRJUO9k_y3nXHMs=
5gumZsNX_U_PuQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEna4K9FZvU3=
aUfvqtRJUO9k_y3nXHMs5gumZsNX_U_PuQ%40mail.gmail.com</a>.<br />

--94eb2c124170c167bd05375f91e8--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 11 Jul 2016 10:58:16 -0700
Raw View
--001a114e0046aadcc505375fe5c2
Content-Type: text/plain; charset=UTF-8

On Sat, Jul 9, 2016 at 9:47 AM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Saturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt Gustafsson wrote:
>>
>> Avoiding these issues with syntax and semantics of declaring types that
>> are zero sized was one of my original motivations for trying the idea of
>> using a zero sized array of any type to get a zero sized variable of an
>> empty type.
>>
>
> Syntax is irrelevant; *semantics* is the main problem. At present, the
> semantics of your proposal are quite unclear. You say that zero-sized
> arrays are a thing, but you don't tell us how they really *behave*. Or
> rather, your explanation of their behavior is contradictory, broken, or
> just confused.
>
> You still haven't answered one of the most important questions. Namely,
> what does this do:
>
> int i[0];
> int *j = i;
> *j = 54;
>
> Is that legal? If that's not legal, then how could *this* be legal:
>
> Type t[0];
> Type *j = t;
> j->SomeMemberFunction();
>
> And if that isn't legal, how could you actually do anything with a
> zero-sized array? How do you access non-static members of such objects? How
> do you call member functions? And so forth.
>

I agree with the rest of your post, but I think you're missing the point of
size 0 arrays in your examples above. None of those should be legal. You're
accessing the one-past-the-end element of an array. Size 0 arrays are
useful when the size is, for instance, dependent on a template parameter.
In fact, std::array already handles this properly in at least some ways --
you can make a std::array with 0 elements and you (appropriately) cannot
access the element at index 0. As well, a std::array of N elements whose
element type is a std::arrays of 0 elements also implicitly behaves
correctly with respect to iteration (though the element type obviously is
not currently size 0 in any [compliant] implementation). What use-cases are
you thinking of where you believe you'd want to actually access a logically
non-existent element?

Anyway, something like the std::array-style behavior is the kind of
behavior we should aspire to have for raw arrays of length 0, although the
only feasible way that I personally see to do this would be to state that
an iterator into an array whose element type is size 0 is *not* a pointer
to that element type. Instead, it should be some other type, such as one
obtained by the hypothetical alias std::array_iterator< T[0] >. Similarly,
*that* is the iterator type that the array should decay to (assuming people
still want decay in order to be partially consistent with all other array
types). What this would change for users is that, when writing generic
code, if you ever create a raw array and need to iterate over it, or if you
want to iterate over a [logically] contiguous container whose element type
may or may not be a size 0 type, you'd need to use the generalized iterator
alias instead of a pointer directly. In the case of array types that are
*not* size 0, the iterator alias would (or at least could) be an alias of
the normally-used pointer type.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEn51FUuuA5FK4oNPS-tCqith5Oi3D5OWcA2-CosofCcxw%40mail.gmail.com.

--001a114e0046aadcc505375fe5c2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
at, Jul 9, 2016 at 9:47 AM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(=
204,204,204);padding-left:1ex"><div dir=3D"ltr"><span class=3D"gmail-">On S=
aturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt Gustafsson wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-le=
ft:1ex"><div dir=3D"ltr">Avoiding these issues with syntax and semantics of=
 declaring types that are zero sized was one of my original motivations for=
 trying the idea of using a zero sized array of any type to get a zero size=
d variable of an empty type.</div></blockquote></span><div><br>Syntax is ir=
relevant; <i>semantics</i> is the main problem. At present, the semantics o=
f your proposal are quite unclear. You say that zero-sized arrays are a thi=
ng, but you don&#39;t tell us how they really <i>behave</i>. Or rather, you=
r explanation of their behavior is contradictory, broken, or just confused.=
<br><br>You still haven&#39;t answered one of the most important questions.=
 Namely, what does this do:<br><br><div style=3D"border:1px solid rgb(187,1=
87,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div>=
<span style=3D"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0=
)"> i</span><span style=3D"color:rgb(102,102,0)">[</span><span style=3D"col=
or:rgb(0,102,102)">0</span><span style=3D"color:rgb(102,102,0)">];</span><s=
pan style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)=
">int</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)">j </span><span styl=
e=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> i</s=
pan><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0=
,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">*</span><span style=
=3D"color:rgb(0,0,0)">j </span><span style=3D"color:rgb(102,102,0)">=3D</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,=
102)">54</span><span style=3D"color:rgb(102,102,0)">;</span></div></code></=
div><br>Is that legal? If that&#39;s not legal, then how could <i>this</i> =
be legal:<br><br><div style=3D"border:1px solid rgb(187,187,187);word-wrap:=
break-word;background-color:rgb(250,250,250)"><code><div><span style=3D"col=
or:rgb(102,0,102)">Type</span><span style=3D"color:rgb(0,0,0)"> t</span><sp=
an style=3D"color:rgb(102,102,0)">[</span><span style=3D"color:rgb(0,102,10=
2)">0</span><span style=3D"color:rgb(102,102,0)">];</span><span style=3D"co=
lor:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,0,102)">Type</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0=
)">*</span><span style=3D"color:rgb(0,0,0)">j </span><span style=3D"color:r=
gb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> t</span><span st=
yle=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>j=
</span><span style=3D"color:rgb(102,102,0)">-&gt;</span><span style=3D"colo=
r:rgb(102,0,102)">SomeMemberFunction</span><span style=3D"color:rgb(102,102=
,0)">();</span></div></code></div><br>And if that isn&#39;t legal, how coul=
d you actually do anything with a zero-sized array? How do you access non-s=
tatic members of such objects? How do you call member functions? And so for=
th.<br></div></div></blockquote><div><br></div><div>I agree with the rest o=
f your post, but I think you&#39;re missing the point of size 0 arrays in y=
our examples above. None of those should be legal. You&#39;re accessing the=
 one-past-the-end element of an array. Size 0 arrays are useful when the si=
ze is, for instance, dependent on a template parameter. In fact, std::array=
 already handles this properly in at least some ways -- you can make a std:=
:array with 0 elements and you (appropriately) cannot access the element at=
 index 0. As well, a std::array of N elements whose element type is a std::=
arrays of 0 elements also implicitly behaves correctly with respect to iter=
ation (though the element type obviously is not currently size 0 in any [co=
mpliant] implementation). What use-cases are you thinking of where you beli=
eve you&#39;d want to actually access a logically non-existent element?</di=
v><div><br></div><div>Anyway, something like the std::array-style behavior =
is the kind of behavior we should aspire to have for raw arrays of length 0=
, although the only feasible way that I personally see to do this would be =
to state that an iterator into an array whose element type is size 0 is <i>=
not</i> a pointer to that element type. Instead, it should be some other ty=
pe, such as one obtained by the hypothetical alias std::array_iterator&lt; =
T[0] &gt;. Similarly, <i>that</i> is the iterator type that the array shoul=
d decay to (assuming people still want decay in order to be partially consi=
stent with all other array types). What this would change for users is that=
, when writing generic code, if you ever create a raw array and need to ite=
rate over it, or if you want to iterate over a [logically] contiguous conta=
iner whose element type may or may not be a size 0 type, you&#39;d need to =
use the generalized iterator alias instead of a pointer directly. In the ca=
se of array types that are <i>not</i> size 0, the iterator alias would (or =
at least could) be an alias of the normally-used pointer type.</div></div><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEn51FUuuA5FK4oNPS-tCqith5Oi3D5O=
WcA2-CosofCcxw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEn51FUuuA5F=
K4oNPS-tCqith5Oi3D5OWcA2-CosofCcxw%40mail.gmail.com</a>.<br />

--001a114e0046aadcc505375fe5c2--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 11 Jul 2016 11:05:06 -0700 (PDT)
Raw View
------=_Part_861_1347470903.1468260306983
Content-Type: multipart/alternative;
 boundary="----=_Part_862_547601693.1468260306988"

------=_Part_862_547601693.1468260306988
Content-Type: text/plain; charset=UTF-8

On Monday, July 11, 2016 at 1:58:20 PM UTC-4, Matt Calabrese wrote:
>
> On Sat, Jul 9, 2016 at 9:47 AM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Saturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt Gustafsson wrote:
>>>
>>> Avoiding these issues with syntax and semantics of declaring types that
>>> are zero sized was one of my original motivations for trying the idea of
>>> using a zero sized array of any type to get a zero sized variable of an
>>> empty type.
>>>
>>
>> Syntax is irrelevant; *semantics* is the main problem. At present, the
>> semantics of your proposal are quite unclear. You say that zero-sized
>> arrays are a thing, but you don't tell us how they really *behave*. Or
>> rather, your explanation of their behavior is contradictory, broken, or
>> just confused.
>>
>> You still haven't answered one of the most important questions. Namely,
>> what does this do:
>>
>> int i[0];
>> int *j = i;
>> *j = 54;
>>
>> Is that legal? If that's not legal, then how could *this* be legal:
>>
>> Type t[0];
>> Type *j = t;
>> j->SomeMemberFunction();
>>
>> And if that isn't legal, how could you actually do anything with a
>> zero-sized array? How do you access non-static members of such objects? How
>> do you call member functions? And so forth.
>>
>
> I agree with the rest of your post, but I think you're missing the point
> of size 0 arrays in your examples above. None of those should be legal.
>

Right, so... what's the point of having a zero-sized array? Remember the
stated goal: to allow you to have *objects* which takes up no space. If
`a[0]` for a zero sized array `a` is always illegal, how could you access
the object?

If you can't access the object, then the concept doesn't solve the problem
it is intended to solve. Remember: his suggestion is not intended to make
code more generic. He explicitly wants to allow zero-sized arrays to allow
you to have empty types which take up no space as member subobjects. Which
requires that a zero-sized array may still have a legitimate object behind
it.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/86ee0d39-a50a-435c-82c7-5ae3b8fbc593%40isocpp.org.

------=_Part_862_547601693.1468260306988
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, July 11, 2016 at 1:58:20 PM UTC-4, Matt Calabre=
se wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote">On Sat, Jul 9, 2016 at 9:47 AM, Nicol Bolas <sp=
an dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated=
-mailto=3D"sYPm3YhoCgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;">jmck...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr"><span>On Saturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt=
 Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:=
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">Avoiding these issues w=
ith syntax and semantics of declaring types that are zero sized was one of =
my original motivations for trying the idea of using a zero sized array of =
any type to get a zero sized variable of an empty type.</div></blockquote><=
/span><div><br>Syntax is irrelevant; <i>semantics</i> is the main problem. =
At present, the semantics of your proposal are quite unclear. You say that =
zero-sized arrays are a thing, but you don&#39;t tell us how they really <i=
>behave</i>. Or rather, your explanation of their behavior is contradictory=
, broken, or just confused.<br><br>You still haven&#39;t answered one of th=
e most important questions. Namely, what does this do:<br><br><div style=3D=
"border:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rg=
b(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">int</span><sp=
an style=3D"color:rgb(0,0,0)"> i</span><span style=3D"color:rgb(102,102,0)"=
>[</span><span style=3D"color:rgb(0,102,102)">0</span><span style=3D"color:=
rgb(102,102,0)">];</span><span style=3D"color:rgb(0,0,0)"><br></span><span =
style=3D"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(=
0,0,0)">j </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=
=3D"color:rgb(0,0,0)"> i</span><span style=3D"color:rgb(102,102,0)">;</span=
><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,1=
02,0)">*</span><span style=3D"color:rgb(0,0,0)">j </span><span style=3D"col=
or:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span=
 style=3D"color:rgb(0,102,102)">54</span><span style=3D"color:rgb(102,102,0=
)">;</span></div></code></div><br>Is that legal? If that&#39;s not legal, t=
hen how could <i>this</i> be legal:<br><br><div style=3D"border:1px solid r=
gb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><co=
de><div><span style=3D"color:rgb(102,0,102)">Type</span><span style=3D"colo=
r:rgb(0,0,0)"> t</span><span style=3D"color:rgb(102,102,0)">[</span><span s=
tyle=3D"color:rgb(0,102,102)">0</span><span style=3D"color:rgb(102,102,0)">=
];</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:r=
gb(102,0,102)">Type</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)">j </s=
pan><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb=
(0,0,0)"> t</span><span style=3D"color:rgb(102,102,0)">;</span><span style=
=3D"color:rgb(0,0,0)"><br>j</span><span style=3D"color:rgb(102,102,0)">-&gt=
;</span><span style=3D"color:rgb(102,0,102)">SomeMemberFunction</span><span=
 style=3D"color:rgb(102,102,0)">();</span></div></code></div><br>And if tha=
t isn&#39;t legal, how could you actually do anything with a zero-sized arr=
ay? How do you access non-static members of such objects? How do you call m=
ember functions? And so forth.<br></div></div></blockquote><div><br></div><=
div>I agree with the rest of your post, but I think you&#39;re missing the =
point of size 0 arrays in your examples above. None of those should be lega=
l.</div></div></div></div></blockquote><div><br>Right, so... what&#39;s the=
 point of having a zero-sized array? Remember the stated goal: to allow you=
 to have <i>objects</i> which takes up no space. If `a[0]` for a zero sized=
 array `a` is always illegal, how could you access the object?<br><br>If yo=
u can&#39;t access the object, then the concept doesn&#39;t solve the probl=
em it is intended to solve. Remember: his suggestion is not intended to mak=
e code more generic. He explicitly wants to allow zero-sized arrays to allo=
w you to have empty types which take up no space as member subobjects. Whic=
h requires that a zero-sized array may still have a legitimate object behin=
d it.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/86ee0d39-a50a-435c-82c7-5ae3b8fbc593%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/86ee0d39-a50a-435c-82c7-5ae3b8fbc593=
%40isocpp.org</a>.<br />

------=_Part_862_547601693.1468260306988--

------=_Part_861_1347470903.1468260306983--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 11 Jul 2016 11:17:09 -0700
Raw View
--001a114e572a3763ae05376029e0
Content-Type: text/plain; charset=UTF-8

On Mon, Jul 11, 2016 at 11:05 AM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Monday, July 11, 2016 at 1:58:20 PM UTC-4, Matt Calabrese wrote:
>>
>> On Sat, Jul 9, 2016 at 9:47 AM, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Saturday, July 9, 2016 at 4:06:43 AM UTC-4, Bengt Gustafsson wrote:
>>>>
>>>> Avoiding these issues with syntax and semantics of declaring types that
>>>> are zero sized was one of my original motivations for trying the idea of
>>>> using a zero sized array of any type to get a zero sized variable of an
>>>> empty type.
>>>>
>>>
>>> Syntax is irrelevant; *semantics* is the main problem. At present, the
>>> semantics of your proposal are quite unclear. You say that zero-sized
>>> arrays are a thing, but you don't tell us how they really *behave*. Or
>>> rather, your explanation of their behavior is contradictory, broken, or
>>> just confused.
>>>
>>> You still haven't answered one of the most important questions. Namely,
>>> what does this do:
>>>
>>> int i[0];
>>> int *j = i;
>>> *j = 54;
>>>
>>> Is that legal? If that's not legal, then how could *this* be legal:
>>>
>>> Type t[0];
>>> Type *j = t;
>>> j->SomeMemberFunction();
>>>
>>> And if that isn't legal, how could you actually do anything with a
>>> zero-sized array? How do you access non-static members of such objects? How
>>> do you call member functions? And so forth.
>>>
>>
>> I agree with the rest of your post, but I think you're missing the point
>> of size 0 arrays in your examples above. None of those should be legal.
>>
>
> Right, so... what's the point of having a zero-sized array? Remember the
> stated goal: to allow you to have *objects* which takes up no space. If
> `a[0]` for a zero sized array `a` is always illegal, how could you access
> the object?
>

You can access the array object perfectly fine, just not an *element* of
the array object, because it doesn't actually have any elements. Examples
of things you can logically do with an array of 0 elements are that you can
pass the object itself around by reference, you can create iterators into
the array (they would be end iterators), you can have a template definition
where the array size is dependent and the definition iterates over the
array (the code wouldn't fail to compile for the size 0 case and would
behave as would be consistent for all other array sizes). Also, depending
on how it's specified and if aliasing rules are relaxed for size 0 types, a
type that contains a size 0 array (most-likely an instantiation of a
template such as std::array) would not contribute to the overall size of
the encapsulating object in a way that is somewhat analogous to EBO.

Maybe this isn't what some people *want* it to be, but I'd argue that this
is what it logically should be (though aliasing aspects are still a bit
subjective).

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEkKguDOtNeHHEbGCj5jWn-j0hEedGpaemEfPPZfZUiivA%40mail.gmail.com.

--001a114e572a3763ae05376029e0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jul 11, 2016 at 11:05 AM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"=
mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</=
span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, =
July 11, 2016 at 1:58:20 PM UTC-4, Matt Calabrese wrote:<span class=3D""><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"g=
mail_quote">On Sat, Jul 9, 2016 at 9:47 AM, Nicol Bolas <span dir=3D"ltr">&=
lt;<a rel=3D"nofollow">jmck...@gmail.com</a>&gt;</span> wrote:<br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-le=
ft:1ex"><div dir=3D"ltr"><span>On Saturday, July 9, 2016 at 4:06:43 AM UTC-=
4, Bengt Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-lef=
t-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">Avoiding these =
issues with syntax and semantics of declaring types that are zero sized was=
 one of my original motivations for trying the idea of using a zero sized a=
rray of any type to get a zero sized variable of an empty type.</div></bloc=
kquote></span><div><br>Syntax is irrelevant; <i>semantics</i> is the main p=
roblem. At present, the semantics of your proposal are quite unclear. You s=
ay that zero-sized arrays are a thing, but you don&#39;t tell us how they r=
eally <i>behave</i>. Or rather, your explanation of their behavior is contr=
adictory, broken, or just confused.<br><br>You still haven&#39;t answered o=
ne of the most important questions. Namely, what does this do:<br><br><div =
style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;background-=
color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">int</=
span><span style=3D"color:rgb(0,0,0)"> i</span><span style=3D"color:rgb(102=
,102,0)">[</span><span style=3D"color:rgb(0,102,102)">0</span><span style=
=3D"color:rgb(102,102,0)">];</span><span style=3D"color:rgb(0,0,0)"><br></s=
pan><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0=
,0,0)"> </span><span style=3D"color:rgb(102,102,0)">*</span><span style=3D"=
color:rgb(0,0,0)">j </span><span style=3D"color:rgb(102,102,0)">=3D</span><=
span style=3D"color:rgb(0,0,0)"> i</span><span style=3D"color:rgb(102,102,0=
)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color=
:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)">j </span><span st=
yle=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(0,102,102)">54</span><span style=3D"color:rgb=
(102,102,0)">;</span></div></code></div><br>Is that legal? If that&#39;s no=
t legal, then how could <i>this</i> be legal:<br><br><div style=3D"border:1=
px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250=
,250)"><code><div><span style=3D"color:rgb(102,0,102)">Type</span><span sty=
le=3D"color:rgb(0,0,0)"> t</span><span style=3D"color:rgb(102,102,0)">[</sp=
an><span style=3D"color:rgb(0,102,102)">0</span><span style=3D"color:rgb(10=
2,102,0)">];</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=
=3D"color:rgb(102,0,102)">Type</span><span style=3D"color:rgb(0,0,0)"> </sp=
an><span style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,=
0,0)">j </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=
=3D"color:rgb(0,0,0)"> t</span><span style=3D"color:rgb(102,102,0)">;</span=
><span style=3D"color:rgb(0,0,0)"><br>j</span><span style=3D"color:rgb(102,=
102,0)">-&gt;</span><span style=3D"color:rgb(102,0,102)">SomeMemberFunction=
</span><span style=3D"color:rgb(102,102,0)">();</span></div></code></div><b=
r>And if that isn&#39;t legal, how could you actually do anything with a ze=
ro-sized array? How do you access non-static members of such objects? How d=
o you call member functions? And so forth.<br></div></div></blockquote><div=
><br></div><div>I agree with the rest of your post, but I think you&#39;re =
missing the point of size 0 arrays in your examples above. None of those sh=
ould be legal.</div></div></div></div></blockquote></span><div><br>Right, s=
o... what&#39;s the point of having a zero-sized array? Remember the stated=
 goal: to allow you to have <i>objects</i> which takes up no space. If `a[0=
]` for a zero sized array `a` is always illegal, how could you access the o=
bject?<br></div></div></blockquote><div><br></div><div>You can access the a=
rray object perfectly fine, just not an <i>element</i> of the array object,=
 because it doesn&#39;t actually have any elements. Examples of things you =
can logically do with an array of 0 elements are that you can pass the obje=
ct itself around by reference, you can create iterators into the array (the=
y would be end iterators), you can have a template definition where the arr=
ay size is dependent and the definition iterates over the array (the code w=
ouldn&#39;t fail to compile for the size 0 case and would behave as would b=
e consistent for all other array sizes). Also, depending on how it&#39;s sp=
ecified and if aliasing rules are relaxed for size 0 types, a type that con=
tains a size 0 array (most-likely an instantiation of a template such as st=
d::array) would not contribute to the overall size of the encapsulating obj=
ect in a way that is somewhat analogous to EBO.</div><div><br></div><div>Ma=
ybe this isn&#39;t what some people <i>want</i>=C2=A0it to be, but I&#39;d =
argue that this is what it logically should be (though aliasing aspects are=
 still a bit subjective).</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEkKguDOtNeHHEbGCj5jWn-j0hEedGpa=
emEfPPZfZUiivA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEkKguDOtNeH=
HEbGCj5jWn-j0hEedGpaemEfPPZfZUiivA%40mail.gmail.com</a>.<br />

--001a114e572a3763ae05376029e0--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 11 Jul 2016 11:42:24 -0700 (PDT)
Raw View
------=_Part_703_1986999204.1468262544848
Content-Type: multipart/alternative;
 boundary="----=_Part_704_877456710.1468262544848"

------=_Part_704_877456710.1468262544848
Content-Type: text/plain; charset=UTF-8

On Monday, July 11, 2016 at 2:17:13 PM UTC-4, Matt Calabrese wrote:
>
> You can access the array object perfectly fine, just not an *element* of
> the array object, because it doesn't actually have any elements. Examples
> of things you can logically do with an array of 0 elements are that you can
> pass the object itself around by reference, you can create iterators into
> the array (they would be end iterators), you can have a template definition
> where the array size is dependent and the definition iterates over the
> array (the code wouldn't fail to compile for the size 0 case and would
> behave as would be consistent for all other array sizes). Also, depending
> on how it's specified and if aliasing rules are relaxed for size 0 types, a
> type that contains a size 0 array (most-likely an instantiation of a
> template such as std::array) would not contribute to the overall size of
> the encapsulating object in a way that is somewhat analogous to EBO.
>
> Maybe this isn't what some people *want* it to be, but I'd argue that
> this is what it logically should be (though aliasing aspects are still a
> bit subjective).
>

I agree. But that behavior is A) not the behavior the OP wants, and B) not
solving the problem the OP wants to use the behavior to solve.

So that would be one more reason not to implement stateless objects as
zero-sized arrays.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2b4dad3f-e3ca-4e5c-9b1a-3e48ba881972%40isocpp.org.

------=_Part_704_877456710.1468262544848
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, July 11, 2016 at 2:17:13 PM UTC-4, Matt Calabre=
se wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote"><div></div><div>You can access the array object=
 perfectly fine, just not an <i>element</i> of the array object, because it=
 doesn&#39;t actually have any elements. Examples of things you can logical=
ly do with an array of 0 elements are that you can pass the object itself a=
round by reference, you can create iterators into the array (they would be =
end iterators), you can have a template definition where the array size is =
dependent and the definition iterates over the array (the code wouldn&#39;t=
 fail to compile for the size 0 case and would behave as would be consisten=
t for all other array sizes). Also, depending on how it&#39;s specified and=
 if aliasing rules are relaxed for size 0 types, a type that contains a siz=
e 0 array (most-likely an instantiation of a template such as std::array) w=
ould not contribute to the overall size of the encapsulating object in a wa=
y that is somewhat analogous to EBO.</div><div><br></div><div>Maybe this is=
n&#39;t what some people <i>want</i>=C2=A0it to be, but I&#39;d argue that =
this is what it logically should be (though aliasing aspects are still a bi=
t subjective).</div></div></div></div></blockquote><div><br>I agree. But th=
at behavior is A) not the behavior the OP wants, and B) not solving the pro=
blem the OP wants to use the behavior to solve. <br><br>So that would be on=
e more reason not to implement stateless objects as zero-sized arrays.<br><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2b4dad3f-e3ca-4e5c-9b1a-3e48ba881972%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2b4dad3f-e3ca-4e5c-9b1a-3e48ba881972=
%40isocpp.org</a>.<br />

------=_Part_704_877456710.1468262544848--

------=_Part_703_1986999204.1468262544848--

.