<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2013/6/3 Don <span dir="ltr"><<a href="mailto:turnyourkidsintocash@nospam.com" target="_blank">turnyourkidsintocash@nospam.com</a>></span><br><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

DMD has always accepted this initializer syntax for static arrays:<br>
<br>
float [50] x = 1.0;<br>
<br>
If this declaration happens inside a function, or in global scope, the compiler sets all members of x to 1.0.  That is, it's the same as:<br>
<br>
float [50] x = void;<br>
x[] = 1.0;<br>
<br>
In my DMD pull requests, I've called this 'block initialization', since there was no standard name for it.<br>
<br>
A lot of code relies on this behaviour, but the spec doesn't mention it!!!<br>
<br>
The problem is not simply that this is unspecified. A long time ago, if this same declaration was a member of a struct declaration, the behaviour was completely different. It used to set x[0] to 1.0, and leave the others at float.init. I'll call this "first-element-initialization"<u></u>, and it still applies in many cases, for example when you use a struct static initializer. Ie, it's the same as:<br>


<br>
float [50] x;<br>
x[0] = 1.0;<br>
<br>
Note however that this part of the compiler has historically been very bug-prone, and the behaviour has changed several times.<br>
<br>
<br>
I didn't know about first-element-initialization when I originally did the CTFE code, so when CTFE is involved, it always does block initialization instead.<br>
Internally, the compiler has two functions, defaultInit() and defaultInitLiteral(). The first does first-element-init, the second does block-init.<br>
There are several other situations which do block initialization (not just CTFE). There are a greater number of situations where first-init can happen, but the most frequently encountered situations use block-init. There are even some foul cases, like bug 10198, where due to a bug in CTFE, you currently get a bizarre mix of both first-init and block-init!<br>


<br>
<br>
So, we have a curious mix of the two behaviours. Which way is correct?<br>
<br>
Personally I'd like to just use block-init everywhere. I personally find first-element-init rather unexpected, but maybe that's just me. I don't know when it would be useful. But regardless, we need to get this sorted out.<br>


It's a blocker for my CTFE work.<br></blockquote><div><br></div><div>First-element-init is definitely a bug. I can argue that nobody wants the strange behavior.</div><div> </div><div><br></div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

Here's an example of some of the oddities:<br>
----<br>
struct S {<br>
   int [3] x;<br>
}<br>
<br>
struct T {<br>
    int [3] x = 8;<br>
}<br>
<br>
struct U {<br>
   int [3][3] y;<br>
}<br>
<br>
void main()<br>
{<br>
   int [3][4] w = 7;<br>
   assert( w[2][2] == 7); // Passes, it was block-initialized<br></blockquote><div><br></div><div>Currently block-initialization for multi-dimensional static array is just only allowed for variable declaration in statement scope.</div>

<div>I'm planning to fix bug 3849 and 7019, but changing this behavior might affect them. As my hope, I'd like to keep this as-is so I've not finished thinking about it well.<br></div><div><br></div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

   S s =  { 8 }; // OK, struct static initializer. first-element-init<br></blockquote><div><br></div><div>This is definitely a bug. Instead, block-init should occur.</div><div> </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


   S r = S( 8 ); // OK, struct literal, block-init.<br>
   T t;          // Default initialized, block-init<br></blockquote><div><br></div><div>OK.</div><div> </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


   assert( s.x[2] == 8); // Fails; it was first-element-initialized<br></blockquote><div><br></div><div>Also, definitely a bug.</div><div> </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


   assert( r.x[2] == 8); // Passes; all elements are 8. Block-init.<br>
   assert( t.x[2] == 8); // Passes; all elements are 8. Block-init.<br></blockquote><div><br></div><div>OK.</div><div> </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


   U u = { 9 };  // Does not compile<br>
   // Error: cannot implicitly convert expression (9) of type int to int[3LU][3LU]<br></blockquote><div><br></div><div>For reasons I've already mentioned in `int [3][4] w = 7;`, I'd like to keep this current behavior.<br>
</div><div>
 </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
}<br>
---<br>
</blockquote></div><br></div><div class="gmail_extra">Kenji Hara</div></div>