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