Quantum Superposition Observed in DMD at Compile Time

John Colvin john.loughran.colvin at gmail.com
Mon Jul 1 05:57:25 UTC 2019


On Monday, 1 July 2019 at 01:42:36 UTC, Meta 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.

Pretty sure that's a compiler bug. Please report.

Here's a simpler example, which for extra buggy joy prints the 
error message twice!

void foo()
{
   size_t[1] nums;
   static foreach (i; 0 .. 1)
     if (false)
       auto a = nums[i - 1];
}

onlineapp.d(6): Error: array index 18446744073709551615 is out of 
bounds nums[0 .. 1]
onlineapp.d(6): Error: array index 18446744073709551615 is out of 
bounds nums[0 .. 1]


More information about the Digitalmars-d mailing list