Object.Error:打印std.algorithm.cartesianProduct结果时的访问冲突

Met*_*eta 4 d phobos

我正在使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

该程序打印出来:

one one
two one
three one
Run Code Online (Sandbox Code Playgroud)

然后抛出访问冲突错误.我是否错误地使用了cartesianProduct,或者这是函数中的错误?

Mih*_*uns 6

可能是两点都有点.这里的问题ct是尝试在编译时进行评估,并生成在运行时使用的结果范围.我想CTFE或cartesianProduct都不会期望这样的情况,并且会发生涉及使用无效内存的不良事件.我认为它应该有工作,或者是编译时错误,但这对你没有帮助,属于bug跟踪器.

这里重要的是,如果将ct初始化移动到单元测试主体或static this()模块构造函数,一切都会有效.您似乎错过的是D在程序启动时不支持全局变量的初始化.分配给global的值总是在编译时评估,这通常"正常工作",经常导致编译时错误(如果初始化不是CTFE),在这种情况下导致奇怪的行为:)

你可能想要的是这段代码:

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

static this()
{
    ct = cartesianProduct(Test1Members, Test2Members);
}
Run Code Online (Sandbox Code Playgroud)

通常,编译时数据和复杂类型(如数组或关联数组)的运行时数据之间的互连对于当前的D前端实现而言非常棘手,需要很多关注.