Object.Error: Access violation while printing result std.algorithm.cartesianProduct

I am using DMD 2.062 for x86.

module test; private enum test1 { one, two, three, } private enum test2 { one, two, three, } auto ct = cartesianProduct([EnumMembers!test1], [EnumMembers!test2]); unittest { import std.stdio; foreach (n, m; ct) { writeln(n, " ", m); } } 

This program prints:

 one one two one three one 

Then an access violation error is thrown. Am I using cartesianProduct incorrectly or is this a bug in the function?

+4
source share
1 answer

A tiny bit of both, I guess. The problem here is that ct tries to evaluate at compile time and creates a range of results that is used at runtime. I think that either CTFE or cartesianProduct do not expect such a scenario, and something bad happens using invalid memory. I think that it should either work or be a compile-time error, but this will not help you and belongs to the error tracker.

What is important here, however, everything will work if you move the ct initialization to the unit-test module or the constructor of the static this() module. What you seem to miss is that D does not support the initialization of global variables when the program starts. The value assigned to the global one is always evaluated at compile time, which often "just works", often leads to a compile-time error (if the initialization does not match CTFE), and in this case leads to strange behavior :)

What you might need is the code:

 auto Test1Members = [ EnumMembers!test1 ]; auto Test2Members = [ EnumMembers!test2 ]; alias CT = typeof(cartesianProduct(Test1Members, Test2Members)); CT ct; static this() { ct = cartesianProduct(Test1Members, Test2Members); } 

In general, the relationship between compile-time data and runtime data for complex types in the form of arrays or associative arrays is very complex with the current implementation of the D interface and requires a lot of attention.

+6
source

All Articles