Почему DMD не может скомпилировать следующий фрагмент кода D? - PullRequest
1 голос
/ 28 сентября 2019

Я изучаю 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 выдает исключение при компиляции точно такого же кода dmd temp.d в Windows 10.

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?

1 Ответ

4 голосов
/ 28 сентября 2019

В 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 вы также можете протестировать свой код с помощью dub, запустив его с --arch=x86_64 или с флагом dmd -m64, где он уже должен работать без изменений.Я рекомендую всегда тестировать ваше приложение как на 32-битном, так и на 64-битном, чтобы убедиться, что вы используете size_t там, где это необходимо.

...