Quantum Superposition Observed in DMD at Compile Time
Meta
jared771 at gmail.com
Mon Jul 1 01:42:36 UTC 2019
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.
More information about the Digitalmars-d
mailing list