为什么 DMD 无法编译以下 D 代码段?

Why DMD is not able to compile the following D code snippet?

我正在学习 D 并使用 run.dlang.io for debugging. The following code below runs without issues on 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 上不起作用?

在 Windows 上,您的应用程序默认构建为 32 位。在 OSX 和 Linux 上(这就是 run.dlang.io 是 运行ning)它默认构建 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 上,您还可以通过 运行 将代码与 --arch=x86_64 或 dmd 标志 -m64 结合使用来测试您的代码,它应该已经可以正常工作而无需更改.我建议始终在 32 位和 64 位上测试您的应用程序,以确保您在需要的地方使用 size_t