Quantum Superposition Observed in DMD at Compile Time

Meta jared771 at gmail.com
Tue Jul 2 13:43:10 UTC 2019


On Tuesday, 2 July 2019 at 13:37:11 UTC, Iain Buclaw wrote:
> On Mon, 1 Jul 2019 at 03:45, Meta via Digitalmars-d 
> <digitalmars-d at puremagic.com> wrote:
>>
>> Jokes aside, this is very strange behaviour.
>>
>> struct Test(T...)
>> {
>>      this(T ts)
>>      {
>>          foreach (i, t; ts)
>>          {
>>              int[ts.length] nums;
>>              if (i % 2 == 0)
>>              {
>>                  nums[i / 2] = i;
>>              }
>>              else
>>              {
>>                  nums[(i - 1) / 2] = i; // Error:array index
>> 9223372036854775807 is out of bounds nums[0 .. 4]
>>              }
>>          }
>>      }
>> }
>>
>> void main()
>> {
>>      auto t = Test!(int, string, double, bool)(0, "", 0, 
>> false);
>> }
>>
>> Of course, the only possible way (i - 1) / 2 can be 
>> 9223372036854775807 is if i == 0 and thus i - 1 underflows. 
>> However, this should never be possible because the else branch 
>> should only be taken when i > 0.
>>
>> After some testing, I realized that this is a very weird 
>> side-effect of constant folding. Regardless of whether the 
>> "else" branch will be taken at runtime, nums[(i - 1) / 2] is 
>> computed *at compile time* for each loop... but, it's not 
>> actually a loop. This is a static foreach (old-style, but this 
>> problem occurs with `static foreach` as well). The loop body 
>> is unrolled N times (where N == ts.length), and as expected, 
>> when I change the foreach to a regular for-loop, this problem 
>> goes away. Also changing the runtime if to static if fixes it.
>>
>> This is very strange behaviour, but understandable after some 
>> investigation. What I don't quite know is whether there should 
>> be a bug report opened for this. It's not technically a bug, I 
>> don't think, but it is certainly unexpected and arguably 
>> should be fixed.
>
> You could have just raised a bugzilla ticket.

I didn't know if this was a bug or not due to the mix of 
compile-time and runtime stuff going on in my example.


More information about the Digitalmars-d mailing list