【问题标题】:Why DMD is not able to compile the following D code snippet?为什么 DMD 无法编译以下 D 代码片段?
【发布时间】:2019-09-28 20:23:49
【问题描述】:

我正在学习 D 并使用run.dlang.io 进行调试。下面的代码在run.dlang.io 上运行没有问题:

import std.stdio;
import std.algorithm;
import std.range;
import std.typecons;

static bool even(Tuple!(ulong, double) a) {
    return (a[0] & 1) == 0;   
}

void main() {
    double[] arr = [31, 22, -3, 44, 51, 26, 47, 58, 19, 10];  
    auto res1 = arr.enumerate.filter!(even).map!(a => a[1]);
    writeln(res1);    
}

但是,DMD32 v2.088 在 Windows 10 上编译完全相同的代码 dmd temp.d 时会引发异常。

Error: function temp.even(Tuple!(ulong, double) a) is not callable using argument types (Tuple!(uint, "index", double, "value")) 

而 LDC 编译器 (1.18.0-beta1):(基于 DMD v2.088.0 和 LLVM 8.0.1)编译相同的文件没有问题。

run.dlang.io 使用 2.087 dmd 编译器,不知何故它神奇地工作,为什么它不能在 Windows 上工作?

【问题讨论】:

    标签: d


    【解决方案1】:

    在 Windows 上,您的应用程序默认是为 32 位构建的。在 OSX 和 Linux(这是 run.dlang.io 正在运行的)上,它默认构建为 64 位。

    因此,数组索引分别为 uint 和 ulong。在您的代码中,您使用了 Tuple!(ulong, double),但在 32 位上,它使用 uint 索引调用。

    您应该使用size_t 作为索引,而不是使用 ulong/uint,它映射到 uint/ulong。这是在object.d 中定义的,默认包含在内。

    因此,如果您将功能更改为

    static bool even(Tuple!(size_t, double) a) {
        return (a[0] & 1) == 0;   
    }
    

    它将在 32 位和 64 位上运行。

    在 Windows 上,您还可以使用 dub 测试您的代码,方法是使用 --arch=x86_64 或使用 dmd 标志 -m64 运行它,它应该已经可以正常工作而无需更改。我建议始终在 32 位和 64 位上测试您的应用程序,以确保您在需要时使用size_t

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-30
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多