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. 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 (&)[]</span>), which is silly. 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 (&)[]</span> or <span style=3D"font-fam=
ily: courier new,monospace;">T (*)[]</span>. 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. That <s=
pan style=3D"font-family: courier new,monospace;">T (&)[]</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. Double=
silliness: you can currently use <span style=3D"font-family: courier new,m=
onospace;">T (&)[]</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 &</span> is valid: <span style=3D"font-family: courier new,monosp=
ace;">T a[non_const_value]; auto &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 (&)[]</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 (&)[]</span>, but not to <span style=3D=
"font-family: courier new,monospace;">T (&)[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;">&</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 (&)[]</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>. 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 (&)[]</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. (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 (&)[X=
], T (&)[], T (*)[X], T (*)[], T & and T * may all alias, in additi=
on to the usual char *, unsigned char * and void *? 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" 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–24, at 12:52 PM, Myriachan <<a href=3D"mailto:myriachan@g=
mail.com">myriachan@gmail.com</a>> 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. </div></blockquote>=
<div><br></div><div>I asked a few weeks ago, and the <a href=3D"http:/=
/cplusplus.github.io/EWG/ewg-active.html#118">EWG issue</a> 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 a paper for EW=
G review, EWG expects to send it forwards to CWG without much 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 (&)[]</=
span> or <span style=3D"font-family: courier new,monospace;">T (*)[]</span>=
.. This restriction seems pointless, as it is easily fully implementab=
le 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 <span style=3D"font-family: courier new,monos=
pace;">T (&)[]</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. Double silliness: you can currently use <span sty=
le=3D"font-family: courier new,monospace;">T (&)[]</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 &</span> is valid: <span style=3D"font-family: 'courier new', monosp=
ace;">T a[non_const_value]; auto &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 (&)[]</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 (&)[]=
</span>, but not to <span style=3D"font-family: 'courier new', monospace;">=
T (&)[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;">&=
</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 (&)[]</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>. 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 (&)[]</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. (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 (&)[], T (*)[X], T (*)[], T & and T * may all alias, in =
addition to the usual char *, unsigned char * and void *? 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’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 <font face=3D"Courier">reinterpret_cast<=
; T(&&)[ N ] >( std::array< T, N >() )</font> and vice ver=
sa shouldn’t be valid. But that’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" 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 <<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>> 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 (&)[]</span> or <span style=3D"font-family:=
courier new,monospace">T (*)[]</span>. This restriction seems pointle=
ss, as it is easily fully implementable and unambiguous in meaning. 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. That <span st=
yle=3D"font-family:courier new,monospace">T (&)[]</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. Double silliness=
: you can currently use <span style=3D"font-family:courier new,monospace">T=
(&)[]</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. 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">&<=
/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>. 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 (&)[]</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. (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. 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 (&)[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 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 <font face=3D"Courier">reinterpret_cast< T(&&)[ N ] =
>( std::array< T, N >() )</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. 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<T, N></span> and <span style=3D"font-family: courier new,monos=
pace;">T (&&)[N]</span> are unrelated types. IMO, the aliasin=
g rules should state that if you have a CV T */&, and T is recursively =
one of the members of class S, then CV S */& should be assumed to alias=
with CV T */&. 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. 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. 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. 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>. <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. 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></span></div><span style=3D"font-family: courier new,monosp=
ace;">auto countof(const T &obj) -> typename std::make_uns=
igned<</span><div dir=3D"ltr"><span style=3D"font-family: courier new,mo=
nospace;"> typename std::iterator_</span><wbr><span =
style=3D"font-family: courier new,monospace;">traits<decltype(obj.begin(=
))>:</span><wbr><span style=3D"font-family: courier new,monospace;">:dif=
ference_type>::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; // Might be better as an enable_if?</span></div><div><span style=
=3D"font-family: courier new,monospace;"> static_assert(is_sam=
e<typename iterator_traits<decltype(obj.</span><wbr><span style=3D"fo=
nt-family: courier new,monospace;">begin())>::iterator_category,</span><=
/div><div><span style=3D"font-family: courier new,monospace;"> =
random_access_iterator_tag>:</span><wbr><span style=
=3D"font-family: courier new,monospace;">:value, "iterator tag is not =
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;"> &nbs=
p; return static_cast<decltype(countof(</span><wbr><span style=3D"font-f=
amily: courier new,monospace;">obj))>(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=
<typename T, std::size_t S></span></div><div dir=3D"ltr"><span style=
=3D"font-family: courier new,monospace;">constexpr std::size_t countof=
(const T (&)[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;"> 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" 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--
.