【问题标题】:Object.Error: Access Violation when printing result of std.algorithm.cartesianProductObject.Error:打印 std.algorithm.cartesianProduct 的结果时发生访问冲突
【发布时间】:2013-03-27 05:56:02
【问题描述】:

我正在为 x86 使用 DMD 2.062。

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);
    }
}

这个程序打印出来:

one one
two one
three one

然后抛出访问冲突错误。我是否错误地使用了笛卡尔产品,或者这是函数中的错误?

【问题讨论】:

    标签: d phobos


    【解决方案1】:

    可能两者都有。这里的问题是 ct 试图在编译时进行评估并产生在运行时使用的结果范围。我猜 CTFE 或 cartesianProduct 都不希望出现这种情况,并且会发生涉及使用无效内存的不良情况。我认为它应该可以工作,或者是编译时错误,但这对您没有帮助并且属于错误跟踪器。

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

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

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

    一般来说,复杂类型(如数组或关联数组)的编译时数据和运行时数据之间的互连对于当前的 D 前端实现非常棘手,需要引起很多关注。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 2020-07-15
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多