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

问题描述 投票:0回答:1

我正在学习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个回答
2
投票

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

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

而不是使用ulong / uint,您应该使用size_t作为索引,它映射到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运行它来使用dub测试您的代码,该代码应该已经可以正常工作而无需更改。我建议始终在32位和64位上同时测试您的应用程序,以确保在需要的地方使用size_t

© www.soinside.com 2019 - 2024. All rights reserved.