Quantum Superposition Observed in DMD at Compile Time

Iain Buclaw ibuclaw at gdcproject.org
Tue Jul 2 13:37:11 UTC 2019


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.

-- 
Iain


More information about the Digitalmars-d mailing list