Topic: Conversion between T (*)[X] and T(*)[] and


Author: Myriachan <myriachan@gmail.com>
Date: Wed, 23 Jul 2014 21:52:27 -0700 (PDT)
Raw View
------=_Part_88_401232627.1406177547994
Content-Type: text/plain; charset=UTF-8

It's been discussed before, and I think recently, but I'm definitely in
agreement that both implicit and static_cast conversion should be allowed
for references and pointers to arrays when converting from known type to
unknown type.  Currently, you can't pass an array of known size (T [X]) to
a function expecting a reference to an array of unknown size (T (&)[]),
which is silly.  Was there ever a consensus in the discussion about fixing
that to be allowed?

In any case, I propose to modify the variable-sized stack array
specification (N3497?) and arrays in general as follows:


1. Remove the restriction that function parameters may not be of type T
(&)[] or T (*)[].  This restriction seems pointless, as it is easily fully
implementable and unambiguous in meaning.  Heck, the newest Visual C++ and
Clang already allow it without even warning - among the Big 3 compilers,
only G++ doesn't allow it.  That T (&)[] and T (*)[] aren't allowed for
parameters but are allowed for return types is silly.  Double silliness:
you can currently use T (&)[] as non-type template parameters to template
functions.

2. Applying typeid(a) to a variable-sized stack array returns the same
thing as it would on an array of unknown bound.

3. Applying decltype() to variable-sized stack array T a[x] returns type T
[].

4. Using auto & is valid: T a[non_const_value]; auto &b = a; makes b be of
type T (&)[].

5. Variable-sized stack arrays T a[x] may bind to properly CV-qualified
references T (&)[], but not to T (&)[Y] for any Y.

6. Applying unary & to a variable-sized stack array T a[x] returns a value
of type T (*)[] that, if dereferenced, is a reference of type T (&)[] that
is bound the same way as changes 4 and 5.

7. No changes to sizeof() versus N3497: it's still ill-formed to do
sizeof(a) on T a[x] for non-constexpr x.  This is akin to sizeof() already
being ill-formed on types T [] and T (&)[].

8. Implementations are free to implement variable-sized stack arrays on a
per-case basis if they so choose, possibly even choosing an implementation
at runtime at each call site.  (For example, if an implementation were to
use a design akin to Microsoft's _malloca and _freea each time an such an
array is allocated.)


Do the aliasing rules need to change to assume that T (&)[X], T (&)[], T
(*)[X], T (*)[], T & and T * may all alias, in addition to the usual char
*, unsigned char * and void *?  I don't understand the wording the aliasing
rules enough to know whether, for example, T (*)[X] and T (*)[] are
different enough types to break the strict aliasing rule.

Melissa

--

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

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

<div dir=3D"ltr">It's been discussed before, and I think recently, but I'm =
definitely in agreement that both implicit and <span style=3D"font-family: =
courier new,monospace;">static_cast</span> conversion should be allowed for=
 references and pointers to arrays when converting from known type to unkno=
wn type.&nbsp; Currently, you can't pass an array of known size (<span styl=
e=3D"font-family: courier new,monospace;">T [X]</span>) to a function expec=
ting a reference to an array of unknown size (<span style=3D"font-family: c=
ourier new,monospace;">T (&amp;)[]</span>), which is silly.&nbsp; Was there=
 ever a consensus in the discussion about fixing that to be allowed?<br><br=
>In any case, I propose to modify the variable-sized stack array specificat=
ion (N3497?) and arrays in general as follows:<br><br><br>1. Remove the res=
triction that function parameters may not be of type <span style=3D"font-fa=
mily: courier new,monospace;">T (&amp;)[]</span> or <span style=3D"font-fam=
ily: courier new,monospace;">T (*)[]</span>.&nbsp; This restriction seems p=
ointless, as it is easily fully implementable and unambiguous in meaning.&n=
bsp; Heck, the newest Visual C++ and Clang already allow it without even wa=
rning - among the Big 3 compilers, only G++ doesn't allow it.&nbsp; That <s=
pan style=3D"font-family: courier new,monospace;">T (&amp;)[]</span> and <s=
pan style=3D"font-family: courier new,monospace;">T (*)[]</span> aren't all=
owed for parameters but are allowed for return types is silly.&nbsp; Double=
 silliness: you can currently use <span style=3D"font-family: courier new,m=
onospace;">T (&amp;)[]</span> as non-type template parameters to template f=
unctions.<br><br>2. Applying <span style=3D"font-family: courier new,monosp=
ace;">typeid(a)</span> to a variable-sized stack array returns the same thi=
ng as it would on an array of unknown bound.<br><br>3. Applying <span style=
=3D"font-family: courier new,monospace;">decltype()</span> to variable-size=
d stack array <span style=3D"font-family: courier new,monospace;">T a[x]</s=
pan> returns type <span style=3D"font-family: courier new,monospace;">T []<=
/span>.<br><br>4. Using <span style=3D"font-family: courier new,monospace;"=
>auto &amp;</span> is valid: <span style=3D"font-family: courier new,monosp=
ace;">T a[non_const_value]; auto &amp;b =3D a;</span> makes <span style=3D"=
font-family: courier new,monospace;">b</span> be of type <span style=3D"fon=
t-family: courier new,monospace;">T (&amp;)[]</span>.<br><br>5. Variable-si=
zed stack arrays <span style=3D"font-family: courier new,monospace;">T a[x]=
</span> may bind to properly CV-qualified references <span style=3D"font-fa=
mily: courier new,monospace;">T (&amp;)[]</span>, but not to <span style=3D=
"font-family: courier new,monospace;">T (&amp;)[Y]</span> for any <span sty=
le=3D"font-family: courier new,monospace;">Y</span>.<br><br>6. Applying una=
ry <span style=3D"font-family: courier new,monospace;">&amp;</span> to a va=
riable-sized stack array <span style=3D"font-family: courier new,monospace;=
">T a[x]</span> returns a value of type <span style=3D"font-family: courier=
 new,monospace;">T (*)[]</span> that, if dereferenced, is a reference of ty=
pe <span style=3D"font-family: courier new,monospace;">T (&amp;)[]</span> t=
hat is bound the same way as changes 4 and 5.<br><br>7. No changes to <span=
 style=3D"font-family: courier new,monospace;">sizeof()</span> versus N3497=
: it's still ill-formed to do <span style=3D"font-family: courier new,monos=
pace;">sizeof(a)</span> on <span style=3D"font-family: courier new,monospac=
e;">T a[x]</span> for non-<span style=3D"font-family: courier new,monospace=
;">constexpr</span> <span style=3D"font-family: courier new,monospace;">x</=
span>.&nbsp; This is akin to <span style=3D"font-family: courier new,monosp=
ace;">sizeof()</span> already being ill-formed on types <span style=3D"font=
-family: courier new,monospace;">T []</span> and <span style=3D"font-family=
: courier new,monospace;">T (&amp;)[]</span>.<br><br>8. Implementations are=
 free to implement variable-sized stack arrays on a per-case basis if they =
so choose, possibly even choosing an implementation at runtime at each call=
 site.&nbsp; (For example, if an implementation were to use a design akin t=
o Microsoft's _malloca and _freea each time an such an array is allocated.)=
<br><br><br>Do the aliasing rules need to change to assume that T (&amp;)[X=
], T (&amp;)[], T (*)[X], T (*)[], T &amp; and T * may all alias, in additi=
on to the usual char *, unsigned char * and void *?&nbsp; I don't understan=
d the wording the aliasing rules enough to know whether, for example, T (*)=
[X] and T (*)[] are different enough types to break the strict aliasing rul=
e.<br><br>Melissa<br></div>

<p></p>

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

------=_Part_88_401232627.1406177547994--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 24 Jul 2014 17:35:22 +0800
Raw View
--Apple-Mail=_02553E3D-E9D7-456B-88F3-5F4FD284FEC3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-07-24, at 12:52 PM, Myriachan <myriachan@gmail.com> wrote:

> It's been discussed before, and I think recently, but I'm definitely in a=
greement that both implicit and static_cast conversion should be allowed fo=
r references and pointers to arrays when converting from known type to unkn=
own type.=20

I asked a few weeks ago, and the EWG issue by Richard Smith went on record =
a few months before that. It says (somewhat anachronistically):

> Discussed in Rapperswil 2014. EWG wishes to encourage Smith to write a pa=
per for EWG review, EWG expects to send it forwards to CWG without much ado=
..

=3D=3D=3D=3D

> 1. Remove the restriction that function parameters may not be of type T (=
&)[] or T (*)[].  This restriction seems pointless, as it is easily fully i=
mplementable and unambiguous in meaning.  Heck, the newest Visual C++ and C=
lang already allow it without even warning - among the Big 3 compilers, onl=
y G++ doesn't allow it.  That T (&)[] and T (*)[] aren't allowed for parame=
ters but are allowed for return types is silly.  Double silliness: you can =
currently use T (&)[] as non-type template parameters to template functions=
..

This is already the resolution of CWG DR 393. It should be part of C++14.

> 2. Applying typeid(a) to a variable-sized stack array returns the same th=
ing as it would on an array of unknown bound.
>=20
> 3. Applying decltype() to variable-sized stack array T a[x] returns type =
T [].

Sounds reasonable. Might be good to directly contact Jens Maurer, or whoeve=
r wrote the latest ARB/dynamic array proposals, if it's not in there alread=
y.

> 4. Using auto & is valid: T a[non_const_value]; auto &b =3D a; makes b be=
 of type T (&)[].
>=20
> 5. Variable-sized stack arrays T a[x] may bind to properly CV-qualified r=
eferences T (&)[], but not to T (&)[Y] for any Y.

These follow logically.

> 6. Applying unary & to a variable-sized stack array T a[x] returns a valu=
e of type T (*)[] that, if dereferenced, is a reference of type T (&)[] tha=
t is bound the same way as changes 4 and 5.
>=20
> 7. No changes to sizeof() versus N3497: it's still ill-formed to do sizeo=
f(a) on T a[x] for non-constexpr x.  This is akin to sizeof() already being=
 ill-formed on types T [] and T (&)[].
>=20
> 8. Implementations are free to implement variable-sized stack arrays on a=
 per-case basis if they so choose, possibly even choosing an implementation=
 at runtime at each call site.  (For example, if an implementation were to =
use a design akin to Microsoft's _malloca and _freea each time an such an a=
rray is allocated.)

These all capture the status quo. I hope that local dynamic array evolution=
 can get out of the quagmire and start proceeding from common practices, wh=
ich are already formally standardized since C99.

> Do the aliasing rules need to change to assume that T (&)[X], T (&)[], T =
(*)[X], T (*)[], T & and T * may all alias, in addition to the usual char *=
, unsigned char * and void *?  I don't understand the wording the aliasing =
rules enough to know whether, for example, T (*)[X] and T (*)[] are differe=
nt enough types to break the strict aliasing rule.

Aliasing (=A73.10/10) deals with memory access in terms of lvalue-to-rvalue=
 conversion. The consensus on the UB list seems to be that it should apply =
to member-access subexpressions as well, but as written it currently doesn'=
t. Arrays, likewise, are a point where people disagree about what they woul=
d like strict aliasing to say (or what they think it already says).

I'd still like to know why reinterpret_cast< T(&&)[ N ] >( std::array< T, N=
 >() ) and vice versa shouldn't be valid. But that's another topic.

--=20

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

--Apple-Mail=_02553E3D-E9D7-456B-88F3-5F4FD284FEC3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;07&ndash;24, at 12:52 PM, Myriachan &lt;<a href=3D"mailto:myriachan@g=
mail.com">myriachan@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-interc=
hange-newline"><blockquote type=3D"cite"><div dir=3D"ltr">It's been discuss=
ed before, and I think recently, but I'm definitely in agreement that both =
implicit and <span style=3D"font-family: courier new,monospace;">static_cas=
t</span> conversion should be allowed for references and pointers to arrays=
 when converting from known type to unknown type.&nbsp; </div></blockquote>=
<div><br></div><div>I asked a few weeks ago, and the&nbsp;<a href=3D"http:/=
/cplusplus.github.io/EWG/ewg-active.html#118">EWG issue</a>&nbsp;by Richard=
 Smith went on record a few months before that. It says (somewhat anachroni=
stically):</div><div><br></div><div><blockquote type=3D"cite">Discussed in =
Rapperswil 2014. EWG wishes to encourage Smith to write&nbsp;a paper for EW=
G review, EWG expects to send it forwards to&nbsp;CWG without much&nbsp;ado=
..</blockquote></div><div>=3D=3D=3D=3D</div><br><blockquote type=3D"cite"><d=
iv dir=3D"ltr">1. Remove the restriction that function parameters may not b=
e of type <span style=3D"font-family: courier new,monospace;">T (&amp;)[]</=
span> or <span style=3D"font-family: courier new,monospace;">T (*)[]</span>=
..&nbsp; This restriction seems pointless, as it is easily fully implementab=
le and unambiguous in meaning.&nbsp; Heck, the newest Visual C++ and Clang =
already allow it without even warning - among the Big 3 compilers, only G++=
 doesn't allow it.&nbsp; That <span style=3D"font-family: courier new,monos=
pace;">T (&amp;)[]</span> and <span style=3D"font-family: courier new,monos=
pace;">T (*)[]</span> aren't allowed for parameters but are allowed for ret=
urn types is silly.&nbsp; Double silliness: you can currently use <span sty=
le=3D"font-family: courier new,monospace;">T (&amp;)[]</span> as non-type t=
emplate parameters to template functions.<br></div></blockquote><div><br></=
div><div>This is already the resolution of CWG DR 393. It should be part of=
 C++14.</div><br><blockquote type=3D"cite"><div dir=3D"ltr">2. Applying <sp=
an style=3D"font-family: 'courier new', monospace;">typeid(a)</span> to a v=
ariable-sized stack array returns the same thing as it would on an array of=
 unknown bound.<br><br>3. Applying <span style=3D"font-family: courier new,=
monospace;">decltype()</span> to variable-sized stack array <span style=3D"=
font-family: courier new,monospace;">T a[x]</span> returns type <span style=
=3D"font-family: courier new,monospace;">T []</span>.<br></div></blockquote=
><div><br></div><div>Sounds reasonable. Might be good to directly contact J=
ens Maurer, or whoever wrote the latest ARB/dynamic array proposals, if it&=
rsquo;s not in there already.</div><br><blockquote type=3D"cite"><div dir=
=3D"ltr">4. Using <span style=3D"font-family: 'courier new', monospace;">au=
to &amp;</span> is valid: <span style=3D"font-family: 'courier new', monosp=
ace;">T a[non_const_value]; auto &amp;b =3D a;</span> makes <span style=3D"=
font-family: 'courier new', monospace;">b</span> be of type <span style=3D"=
font-family: 'courier new', monospace;">T (&amp;)[]</span>.</div></blockquo=
te><blockquote type=3D"cite"><br></blockquote><blockquote type=3D"cite"><di=
v dir=3D"ltr">5. Variable-sized stack arrays <span style=3D"font-family: 'c=
ourier new', monospace;">T a[x]</span> may bind to properly CV-qualified re=
ferences <span style=3D"font-family: 'courier new', monospace;">T (&amp;)[]=
</span>, but not to <span style=3D"font-family: 'courier new', monospace;">=
T (&amp;)[Y]</span> for any <span style=3D"font-family: 'courier new', mono=
space;">Y</span>.<br></div></blockquote><div><br></div><div>These follow lo=
gically.</div><div><br></div><blockquote type=3D"cite"><div dir=3D"ltr">6. =
Applying unary <span style=3D"font-family: 'courier new', monospace;">&amp;=
</span> to a variable-sized stack array <span style=3D"font-family: 'courie=
r new', monospace;">T a[x]</span> returns a value of type <span style=3D"fo=
nt-family: 'courier new', monospace;">T (*)[]</span> that, if dereferenced,=
 is a reference of type <span style=3D"font-family: 'courier new', monospac=
e;">T (&amp;)[]</span> that is bound the same way as changes 4 and 5.<br><b=
r>7. No changes to <span style=3D"font-family: courier new,monospace;">size=
of()</span> versus N3497: it's still ill-formed to do <span style=3D"font-f=
amily: courier new,monospace;">sizeof(a)</span> on <span style=3D"font-fami=
ly: courier new,monospace;">T a[x]</span> for non-<span style=3D"font-famil=
y: courier new,monospace;">constexpr</span> <span style=3D"font-family: cou=
rier new,monospace;">x</span>.&nbsp; This is akin to <span style=3D"font-fa=
mily: courier new,monospace;">sizeof()</span> already being ill-formed on t=
ypes <span style=3D"font-family: courier new,monospace;">T []</span> and <s=
pan style=3D"font-family: courier new,monospace;">T (&amp;)[]</span>.<br><b=
r>8. Implementations are free to implement variable-sized stack arrays on a=
 per-case basis if they so choose, possibly even choosing an implementation=
 at runtime at each call site.&nbsp; (For example, if an implementation wer=
e to use a design akin to Microsoft's _malloca and _freea each time an such=
 an array is allocated.)<br></div></blockquote><div><br></div><div>These al=
l capture the status quo. I hope that local dynamic array evolution can get=
 out of the quagmire and start proceeding from common practices, which are =
already formally standardized since C99.</div><br><blockquote type=3D"cite"=
><div dir=3D"ltr">Do the aliasing rules need to change to assume that T (&a=
mp;)[X], T (&amp;)[], T (*)[X], T (*)[], T &amp; and T * may all alias, in =
addition to the usual char *, unsigned char * and void *?&nbsp; I don't und=
erstand the wording the aliasing rules enough to know whether, for example,=
 T (*)[X] and T (*)[] are different enough types to break the strict aliasi=
ng rule.<br></div></blockquote><div><br></div></div>Aliasing (=A73.10/10) d=
eals with memory access in terms of lvalue-to-rvalue conversion. The consen=
sus on the UB list seems to be that it should apply to member-access subexp=
ressions as well, but as written it currently doesn&rsquo;t. Arrays, likewi=
se, are a point where people disagree about what they would like strict ali=
asing to say (or what they think it already says).<div><br></div><div>I&rsq=
uo;d still like to know why&nbsp;<font face=3D"Courier">reinterpret_cast&lt=
; T(&amp;&amp;)[ N ] &gt;( std::array&lt; T, N &gt;() )</font> and vice ver=
sa shouldn&rsquo;t be valid. But that&rsquo;s another topic.</div><div><br>=
</div></body></html>

<p></p>

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

--Apple-Mail=_02553E3D-E9D7-456B-88F3-5F4FD284FEC3--

.


Author: Myriachan <myriachan@gmail.com>
Date: Fri, 25 Jul 2014 21:21:05 -0700 (PDT)
Raw View
------=_Part_2369_903089486.1406348465632
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, July 24, 2014 2:35:36 AM UTC-7, David Krauss wrote:
>
>
> On 2014=E2=80=9307=E2=80=9324, at 12:52 PM, Myriachan <myri...@gmail.com =
<javascript:>>=20
> wrote:
>
> 1. Remove the restriction that function parameters may not be of type T=
=20
> (&)[] or T (*)[].  This restriction seems pointless, as it is easily=20
> fully implementable and unambiguous in meaning.  Heck, the newest Visual=
=20
> C++ and Clang already allow it without even warning - among the Big 3=20
> compilers, only G++ doesn't allow it.  That T (&)[] and T (*)[] aren't=20
> allowed for parameters but are allowed for return types is silly.  Double=
=20
> silliness: you can currently use T (&)[] as non-type template parameters=
=20
> to template functions.
>
>
> This is already the resolution of CWG DR 393. It should be part of C++14.
>
> 2. Applying typeid(a) to a variable-sized stack array returns the same=20
> thing as it would on an array of unknown bound.
>
> 3. Applying decltype() to variable-sized stack array T a[x] returns type =
T=20
> [].
>
>
> Sounds reasonable. Might be good to directly contact Jens Maurer, or=20
> whoever wrote the latest ARB/dynamic array proposals, if it=E2=80=99s not=
 in there=20
> already.
>

I sent an email to Lawrence Crowl about this.  Thanks!

> 6. Applying unary & to a variable-sized stack array T a[x] returns a=20
> value of type T (*)[] that, if dereferenced, is a reference of type T=20
> (&)[] that is bound the same way as changes 4 and 5.
>
> 7. No changes to sizeof() versus N3497: it's still ill-formed to do=20
> sizeof(a) on T a[x] for non-constexpr x.  This is akin to sizeof()=20
> already being ill-formed on types T [] and T (&)[].
>
> 8. Implementations are free to implement variable-sized stack arrays on a=
=20
> per-case basis if they so choose, possibly even choosing an implementatio=
n=20
> at runtime at each call site.  (For example, if an implementation were to=
=20
> use a design akin to Microsoft's _malloca and _freea each time an such an=
=20
> array is allocated.)
>
>
> These all capture the status quo. I hope that local dynamic array=20
> evolution can get out of the quagmire and start proceeding from common=20
> practices, which are already formally standardized since C99.
>

C99 went too far with its runtime-bounded array design, which is part of=20
why there's this issue in the first place - C++ doesn't want the whole=20
thing.  sizeof() in C99 isn't a constant expression when applied to a=20
runtime-bounded array.
=20

> Do the aliasing rules need to change to assume that T (&)[X], T (&)[], T=
=20
> (*)[X], T (*)[], T & and T * may all alias, in addition to the usual char=
=20
> *, unsigned char * and void *?  I don't understand the wording the aliasi=
ng=20
> rules enough to know whether, for example, T (*)[X] and T (*)[] are=20
> different enough types to break the strict aliasing rule.
>
>
> Aliasing (=C2=A73.10/10) deals with memory access in terms of lvalue-to-r=
value=20
> conversion. The consensus on the UB list seems to be that it should apply=
=20
> to member-access subexpressions as well, but as written it currently=20
> doesn=E2=80=99t. Arrays, likewise, are a point where people disagree abou=
t what=20
> they would like strict aliasing to say (or what they think it already say=
s).
>
> I=E2=80=99d still like to know why reinterpret_cast< T(&&)[ N ] >( std::a=
rray< T,=20
> N >() ) and vice versa shouldn=E2=80=99t be valid. But that=E2=80=99s ano=
ther topic.
>

Yes, that case is hard to resolve with strict aliasing rules.  It's=20
definitely defined as giving you a valid pointer due to std::array being=20
standard-layout, but std::array<T, N> and T (&&)[N] are unrelated types. =
=20
IMO, the aliasing rules should state that if you have a CV T */&, and T is=
=20
recursively one of the members of class S, then CV S */& should be assumed=
=20
to alias with CV T */&.  This would need to be transitive; a class with a=
=20
char or unsigned char array as members needs to assume to alias with=20
anything, because of e.g. std::aligned_storage.  Since the aliasing rules=
=20
are about as clear as mud to me right now, I don't really know whether this=
=20
might already be true.

I did have some other crazy/more controversial ideas, though. =3D)

1. Add "member functions" *CV* T *begin() *CV* and *CV* T *end() *CV* to=20
arrays.  It would definitely be a little awkward for arrays to have member=
=20
functions, but they'd be hardwired and such, and presumably trying to=20
acquire a member function pointer to them wouldn't be allowed for sanity's=
=20
sake.  This would eliminate the current special-casing in range-based for=
=20
for arrays: all range-based for loops would be defined as begin() and end()=
.. =20
begin() would be allowed on arrays of unknown bound, but obviously, end()=
=20
would not be.  The compiler would presumably be smart and optimize end() -=
=20
begin() as a compile-time value for non-runtime-bound arrays.

2. With begin() and end(), we could define a std::countof():

template <typename T>
auto countof(const T &obj) -> typename std::make_unsigned<
    typename std::iterator_traits<decltype(obj.begin())>:
:difference_type>::type
{
    // Might be better as an enable_if?
    static_assert(is_same<typename iterator_traits<decltype(obj.
begin())>::iterator_category,
        random_access_iterator_tag>::value, "iterator tag is not of random=
=20
access category");
    return static_cast<decltype(countof(obj))>(obj.end() - obj.begin());
}

template <typename T, std::size_t S>
constexpr std::size_t countof(const T (&)[S])
{
    return S;
}

A bit more complicated than this to get all the details right, but you get=
=20
the idea.

Melissa

--=20

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

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

<div dir=3D"ltr">On Thursday, July 24, 2014 2:35:36 AM UTC-7, David Krauss =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:=
break-word"><br><div><div>On 2014=E2=80=9307=E2=80=9324, at 12:52 PM, Myria=
chan &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"nM1zp48fx-4J" onmousedown=3D"this.href=3D'javascript:';return true;" oncli=
ck=3D"this.href=3D'javascript:';return true;">myri...@gmail.com</a>&gt; wro=
te:</div><br><blockquote type=3D"cite"><div dir=3D"ltr">1. Remove the restr=
iction that function parameters may not be of type <span style=3D"font-fami=
ly:courier new,monospace">T (&amp;)[]</span> or <span style=3D"font-family:=
courier new,monospace">T (*)[]</span>.&nbsp; This restriction seems pointle=
ss, as it is easily fully implementable and unambiguous in meaning.&nbsp; H=
eck, the newest Visual C++ and Clang already allow it without even warning =
- among the Big 3 compilers, only G++ doesn't allow it.&nbsp; That <span st=
yle=3D"font-family:courier new,monospace">T (&amp;)[]</span> and <span styl=
e=3D"font-family:courier new,monospace">T (*)[]</span> aren't allowed for p=
arameters but are allowed for return types is silly.&nbsp; Double silliness=
: you can currently use <span style=3D"font-family:courier new,monospace">T=
 (&amp;)[]</span> as non-type template parameters to template functions.<br=
></div></blockquote><div><br></div><div>This is already the resolution of C=
WG DR 393. It should be part of C++14.</div><br><blockquote type=3D"cite"><=
div dir=3D"ltr">2. Applying <span style=3D"font-family:'courier new',monosp=
ace">typeid(a)</span> to a variable-sized stack array returns the same thin=
g as it would on an array of unknown bound.<br><br>3. Applying <span style=
=3D"font-family:courier new,monospace">decltype()</span> to variable-sized =
stack array <span style=3D"font-family:courier new,monospace">T a[x]</span>=
 returns type <span style=3D"font-family:courier new,monospace">T []</span>=
..<br></div></blockquote><div><br></div><div>Sounds reasonable. Might be goo=
d to directly contact Jens Maurer, or whoever wrote the latest ARB/dynamic =
array proposals, if it=E2=80=99s not in there already.</div></div></div></b=
lockquote><div><br>I sent an email to Lawrence Crowl about this.&nbsp; Than=
ks!</div><div></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=
=3D"word-wrap:break-word"><div><blockquote type=3D"cite"><div dir=3D"ltr">6=
.. Applying unary <span style=3D"font-family:'courier new',monospace">&amp;<=
/span> to a variable-sized stack array <span style=3D"font-family:'courier =
new',monospace">T a[x]</span> returns a value of type <span style=3D"font-f=
amily:'courier new',monospace">T (*)[]</span> that, if dereferenced, is a r=
eference of type <span style=3D"font-family:'courier new',monospace">T (&am=
p;)[]</span> that is bound the same way as changes 4 and 5.<br><br>7. No ch=
anges to <span style=3D"font-family:courier new,monospace">sizeof()</span> =
versus N3497: it's still ill-formed to do <span style=3D"font-family:courie=
r new,monospace">sizeof(a)</span> on <span style=3D"font-family:courier new=
,monospace">T a[x]</span> for non-<span style=3D"font-family:courier new,mo=
nospace">constexpr</span> <span style=3D"font-family:courier new,monospace"=
>x</span>.&nbsp; This is akin to <span style=3D"font-family:courier new,mon=
ospace">sizeof()</span> already being ill-formed on types <span style=3D"fo=
nt-family:courier new,monospace">T []</span> and <span style=3D"font-family=
:courier new,monospace">T (&amp;)[]</span>.<br><br>8. Implementations are f=
ree to implement variable-sized stack arrays on a per-case basis if they so=
 choose, possibly even choosing an implementation at runtime at each call s=
ite.&nbsp; (For example, if an implementation were to use a design akin to =
Microsoft's _malloca and _freea each time an such an array is allocated.)<b=
r></div></blockquote><div><br></div><div>These all capture the status quo. =
I hope that local dynamic array evolution can get out of the quagmire and s=
tart proceeding from common practices, which are already formally standardi=
zed since C99.</div></div></div></blockquote><div><br>C99 went too far with=
 its runtime-bounded array design, which is part of why there's this issue =
in the first place - C++ doesn't want the whole thing.&nbsp; sizeof() in C9=
9 isn't a constant expression when applied to a runtime-bounded array.<br>&=
nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-=
wrap:break-word"><div><blockquote type=3D"cite"><div dir=3D"ltr">Do the ali=
asing rules need to change to assume that T (&amp;)[X], T (&amp;)[], T (*)[=
X], T (*)[], T &amp; and T * may all alias, in addition to the usual char *=
, unsigned char * and void *?&nbsp; I don't understand the wording the alia=
sing rules enough to know whether, for example, T (*)[X] and T (*)[] are di=
fferent enough types to break the strict aliasing rule.<br></div></blockquo=
te><div><br></div></div>Aliasing (=C2=A73.10/10) deals with memory access i=
n terms of lvalue-to-rvalue conversion. The consensus on the UB list seems =
to be that it should apply to member-access subexpressions as well, but as =
written it currently doesn=E2=80=99t. Arrays, likewise, are a point where p=
eople disagree about what they would like strict aliasing to say (or what t=
hey think it already says).<div><br></div><div>I=E2=80=99d still like to kn=
ow why&nbsp;<font face=3D"Courier">reinterpret_cast&lt; T(&amp;&amp;)[ N ] =
&gt;( std::array&lt; T, N &gt;() )</font> and vice versa shouldn=E2=80=99t =
be valid. But that=E2=80=99s another topic.</div></div></blockquote><div><b=
r>Yes, that case is hard to resolve with strict aliasing rules.&nbsp; It's =
definitely defined as giving you a valid pointer due to std::array being st=
andard-layout, but <span style=3D"font-family: courier new,monospace;">std:=
:array&lt;T, N&gt;</span> and <span style=3D"font-family: courier new,monos=
pace;">T (&amp;&amp;)[N]</span> are unrelated types.&nbsp; IMO, the aliasin=
g rules should state that if you have a CV T */&amp;, and T is recursively =
one of the members of class S, then CV S */&amp; should be assumed to alias=
 with CV T */&amp;.&nbsp; This would need to be transitive; a class with a =
char or unsigned char array as members needs to assume to alias with anythi=
ng, because of e.g. std::aligned_storage.&nbsp; Since the aliasing rules ar=
e about as clear as mud to me right now, I don't really know whether this m=
ight already be true.<br><br>I did have some other crazy/more controversial=
 ideas, though. =3D)<br><br>1. Add "member functions" <span style=3D"font-f=
amily: courier new,monospace;"><i>CV</i> T *begin() <i>CV</i></span> and <s=
pan style=3D"font-family: courier new,monospace;"><i>CV</i> T *end() <i>CV<=
/i></span> to arrays.&nbsp; It would definitely be a little awkward for arr=
ays to have member functions, but they'd be hardwired and such, and presuma=
bly trying to acquire a member function pointer to them wouldn't be allowed=
 for sanity's sake.&nbsp; This would eliminate the current special-casing i=
n range-based <span style=3D"font-family: courier new,monospace;">for</span=
> for arrays: all range-based <span style=3D"font-family: courier new,monos=
pace;">for</span> loops would be defined as <span style=3D"font-family: cou=
rier new,monospace;">begin()</span> and <span style=3D"font-family: courier=
 new,monospace;">end()</span>.&nbsp; <span style=3D"font-family: courier ne=
w,monospace;">begin()</span> would be allowed on arrays of unknown bound, b=
ut obviously, <span style=3D"font-family: courier new,monospace;">end()</sp=
an> would not be.&nbsp; The compiler would presumably be smart and optimize=
 <span style=3D"font-family: courier new,monospace;">end() - begin()</span>=
 as a compile-time value for non-runtime-bound arrays.<br><br>2. With <span=
 style=3D"font-family: courier new,monospace;">begin()</span> and <span sty=
le=3D"font-family: courier new,monospace;">end()</span>, we could define a =
<span style=3D"font-family: courier new,monospace;">std::countof()</span>:<=
br><br><div><span style=3D"font-family: courier new,monospace;">template &l=
t;typename T&gt;</span></div><span style=3D"font-family: courier new,monosp=
ace;">auto&nbsp;countof(const T &amp;obj) -&gt;&nbsp;typename std::make_uns=
igned&lt;</span><div dir=3D"ltr"><span style=3D"font-family: courier new,mo=
nospace;">&nbsp; &nbsp;&nbsp;typename&nbsp;std::iterator_</span><wbr><span =
style=3D"font-family: courier new,monospace;">traits&lt;decltype(obj.begin(=
))&gt;:</span><wbr><span style=3D"font-family: courier new,monospace;">:dif=
ference_type&gt;::type</span><div><span style=3D"font-family: courier new,m=
onospace;">
{</span></div><div><span style=3D"font-family: courier new,monospace;">&nbs=
p; &nbsp; // Might be better as an enable_if?</span></div><div><span style=
=3D"font-family: courier new,monospace;">&nbsp; &nbsp; static_assert(is_sam=
e&lt;typename iterator_traits&lt;decltype(obj.</span><wbr><span style=3D"fo=
nt-family: courier new,monospace;">begin())&gt;::iterator_category,</span><=
/div><div><span style=3D"font-family: courier new,monospace;">&nbsp; &nbsp;=
 &nbsp; &nbsp;&nbsp;random_access_iterator_tag&gt;:</span><wbr><span style=
=3D"font-family: courier new,monospace;">:value, "iterator tag is not&nbsp;=
of random access category");</span></div><span style=3D"font-family: courie=
r new,monospace;">
</span><div><span style=3D"font-family: courier new,monospace;">&nbsp; &nbs=
p; return static_cast&lt;decltype(countof(</span><wbr><span style=3D"font-f=
amily: courier new,monospace;">obj))&gt;(obj.end() - obj.begin());</span></=
div><div><span style=3D"font-family: courier new,monospace;">}</span></div>=
<div><br></div><span style=3D"font-family: courier new,monospace;">template=
 &lt;typename T, std::size_t S&gt;</span></div><div dir=3D"ltr"><span style=
=3D"font-family: courier new,monospace;">constexpr&nbsp;std::size_t countof=
(const&nbsp;T (&amp;)[S])</span></div><span style=3D"font-family: courier n=
ew,monospace;">
</span><div dir=3D"ltr"><span style=3D"font-family: courier new,monospace;"=
>{</span></div><div dir=3D"ltr"><span style=3D"font-family: courier new,mon=
ospace;">&nbsp; &nbsp; return S;</span></div><div dir=3D"ltr"><span style=
=3D"font-family: courier new,monospace;">}</span></div><br>A bit more compl=
icated than this to get all the details right, but you get the idea.<br><br=
>Melissa<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2369_903089486.1406348465632--

.