digitalmars.D - T.init for static arrays?
- Walter Bright <newshound1 digitalmars.com> Mar 13 2010
- grauzone <none example.net> Mar 13 2010
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Mar 13 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Mar 13 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Mar 15 2010
Currently, given an array:
alias T[3] A;
A a;
the default initializer for A, A.init, is T.init. It is done this way
for memory efficiency, as:
a = A.init;
doesn't need to create an array for the rvalue. But it does cause
generic programming problems, especially with the advent of static
arrays now being passed by value rather than by ref.
So, I propose changing A.init from being T.init to being [T.init,
T.init, T.init].
What do you think?
Mar 13 2010
Walter Bright wrote:Currently, given an array: alias T[3] A; A a; the default initializer for A, A.init, is T.init. It is done this way for memory efficiency, as: a = A.init; doesn't need to create an array for the rvalue. But it does cause generic programming problems, especially with the advent of static arrays now being passed by value rather than by ref. So, I propose changing A.init from being T.init to being [T.init, T.init, T.init]. What do you think?
This assert should never fail: T x; assert(x is T.init); (Right now it fails for floats because of NaN - can we fix this too? "is" should always do byte comparisons.)
Mar 13 2010
On 03/13/2010 02:13 PM, Walter Bright wrote:Currently, given an array: alias T[3] A; A a; the default initializer for A, A.init, is T.init. It is done this way for memory efficiency, as: a = A.init; doesn't need to create an array for the rvalue. But it does cause generic programming problems, especially with the advent of static arrays now being passed by value rather than by ref. So, I propose changing A.init from being T.init to being [T.init, T.init, T.init]. What do you think?
The irregularity of .init for arrays has been a huge source of problems. I'm very glad you're looking into fixing it. My understanding is that you propose to transform A.init into a literal with as many elements as the length of the array. That has a an issue. Currently array literals default to T[], not T[N]. So this would do the unexpected: alias int[3] A; A a; auto b = A.init; assert(is(typeof(b) == int[]); // pass I was thinking of rewriting (T[N]).init as: { T[N] result; return result; }() i.e. an rvalue of type T[N]. The lambda should be CTFE-able and does not occupy static storage because it creates the temporary on the stack (well, for large arrays the compiler would be free to resort to dynamic allocation). Your solution works if you rewrite (T[N]).init as: (cast(T[N]) [ T.init, T.init, T.init, ... ]) Andrei
Mar 13 2010
--00032557aed206250e0481b514ba Content-Type: text/plain; charset=ISO-8859-1 On Sat, Mar 13, 2010 at 21:13, Walter Bright <newshound1 digitalmars.com>wrote:Currently, given an array: alias T[3] A; A a; the default initializer for A, A.init, is T.init. It is done this way for memory efficiency, as: a = A.init; doesn't need to create an array for the rvalue. But it does cause generic programming problems, especially with the advent of static arrays now being passed by value rather than by ref. So, I propose changing A.init from being T.init to being [T.init, T.init, T.init]. What do you think?
That's bug 3826 http://d.puremagic.com/issues/show_bug.cgi?id=3826 I'm all for A.init being [T.init (n times)], as it indeed broke some of my code, so thank you for the suggestion Walter. I was very surprised to see that A.init was T.init. Andrei:My understanding is that you propose to transform A.init into a literal
as the length of the array. That has a an issue. Currently array literals default to T[], not T[N].
Ah, yes.So this would do the unexpected:
alias int[3] A; A a; auto b = A.init; assert(is(typeof(b) == int[]); // pass
Currently, this does something as unexpected (at least for me): assert( !is (typeof(b) == typeof(a))); // b is an int, a is a int[3] In parallel to what grauzone said, I think this assert should never fail: T x; assert(is(typeof(x) == typeof(T.init)); But then I only use small-size static arrays, as parameters in templates. By small, I mean less than a dozen elements. Other using bigger arrays may shout at this change... Philippe --00032557aed206250e0481b514ba Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Sat, Mar 13, 2010 at 21:13, Walter Br= ight <span dir=3D"ltr"><<a href=3D"mailto:newshound1 digitalmars.com">ne= wshound1 digitalmars.com</a>></span> wrote:<br><blockquote class=3D"gmai= l_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204= , 204, 204); padding-left: 1ex;"> Currently, given an array:<br> <br> =A0 alias T[3] A;<br> =A0 A a;<br> <br> the default initializer for A, A.init, is T.init. It is done this way for m= emory efficiency, as:<br> <br> =A0 a =3D A.init;<br> <br> doesn't need to create an array for the rvalue. But it does cause gener= ic programming problems, especially with the advent of static arrays now be= ing passed by value rather than by ref.<br> <br> So, I propose changing A.init from being T.init to being [T.init, T.init, T= .init].<br> <br> What do you think?<br></blockquote><div><br>That's bug 3826<br><br><a h= ref=3D"http://d.puremagic.com/issues/show_bug.cgi?id=3D3826">http://d.purem= agic.com/issues/show_bug.cgi?id=3D3826</a> <br></div></div><br>I'm all = for A.init being [T.init (n times)], as it indeed broke some of my code, so= thank you for the suggestion Walter. <br> I was very surprised to see that A.init was T.init. <br><br>Andrei:<br>>= My understanding is that you propose to transform A.init into a literal=20 with as many elements <br>>as the length of the array. That has a an iss= ue. <br>>Currently array literals default to T[], not T[N]. <br><br>Ah, = yes.<br><br>>So this would do the=20 unexpected:<br> <br> >alias int[3] A;<br> >A a;<br> >auto b =3D =A0A.init;<br> >assert(is(typeof(b) =3D=3D int[]); // pass<br> <br>Currently, this does something as unexpected (at least for me):<br><br>= assert( !is (typeof(b) =3D=3D typeof(a))); // b is an int, a is a int[3]<br=<br>In parallel to what grauzone said, I think this assert should never fa=
<br>T x;<br>assert(is(typeof(x) =3D=3D typeof(T.init));<br><br><br>But then= I only use small-size static arrays, as parameters in templates. By small,= I mean less than a dozen elements. Other using bigger arrays may shout at = this change...<br> <br><br>=A0Philippe<br><br> --00032557aed206250e0481b514ba--
Mar 13 2010
On Sat, 13 Mar 2010 15:13:26 -0500, Walter Bright <newshound1 digitalmars.com> wrote:Currently, given an array: alias T[3] A; A a; the default initializer for A, A.init, is T.init. It is done this way for memory efficiency, as: a = A.init; doesn't need to create an array for the rvalue. But it does cause generic programming problems, especially with the advent of static arrays now being passed by value rather than by ref. So, I propose changing A.init from being T.init to being [T.init, T.init, T.init]. What do you think?
Is that going to allocate heap data as the current array literal does? If so, it's a step backwards. It needs to be ROM data. -Steve
Mar 15 2010









grauzone <none example.net> 