9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

D言語の更新まとめ 2019年11月版(dmd 2.089.0)

Posted at

はじめに

D言語の公式コンパイラである dmd が更新され、最新バージョンである 2.089.0 が 2019/11/02 にリリースされました。

今回もほぼ予定通りのスケジュールで、言語的な強化は控えめながらツール周りでいくつか目立った強化が行われました。
また不具合修正の一環で多数の改善が入っているので、これもいくつか拾っておきたいと思います。

より細かい内容は下記リンクからChangeLogや公式ブログの原文をご覧ください。

また、前回9月ののリリースまとめは以下になります。

変更点目次

コンパイラ変更点

  • foreach ループで許可されていた変数のshadowingが廃止されました。
  • is式が constinoutshared の組み合わせに正確に一致するようになりました。
  • template mixin 中の extern(C) 宣言がグローバルスコープで使われたとき、Cのマングルでシンボルを生成します。
  • Digital Marsのツールチェインにおけるデフォルトのリンカが optlink.exe になります。
  • Issue 6952のため、新しく -Xcc コンパイラフラグが追加されました。

改善点

  • Bugzilla 809: lazyな引数はdelegateに変換できるべきです。
  • Bugzilla 1547: デフォルト引数の値は暗黙的なopCallを使うべきです。
  • Bugzilla 3004: 不正なpragmaのハンドリングを改善
  • Bugzilla 18272: -gfのchangelogとドキュメントがない (参照された型について不可解なデバッグ情報が出力される)
  • Bugzilla 18617: 式がdeprecatedであるか確かめるために __traits(deprecated, expr)が必要です。

ランタイム変更点

  • core.atomicatomicFetchAddatomicFetchSub を追加します。
  • wstatuspure@safe にします。
    • 訳注)Posixの wait(2)pure/@safe にする、という意味のようです

改善点

  • Bugzilla 8831: core.atomic に 異なる戻り値のcompare-and-swap 関数を追加します。
  • Bugzilla 13826: volatileLoadvolatileStorecore.volatile へ移動します。
  • Bugzilla 15007: core.atomic を C++11 に合わせる
  • Bugzilla 20105: core.atomiccas 関数が不完全
  • Bugzilla 20106: core.atomicatomicFenceMemoryOrder の指定を受け付けない
  • Bugzilla 20107: core.atomic の Memory order にキーが不足している

訳注)いくつかをまとめて atomicFetchAdd あたりに還元されており、トピックとしては core.volatile の追加が大きいです

ライブラリ変更点

  • std.traits.Unconst を追加

改善点

  • Bugzilla 20147: std.bigint.BigInt と浮動小数点型の間で比較(==, >, >=, <=, <)が有効になりました。
  • Bugzilla 20159: std.math.scalbn がCTFE可能となりました。
  • Bugzilla 20192: std.math.isSubnormal がCTFE可能となりました。
  • Bugzilla 20196: std.math.isNormal がCTFE可能となりました。
  • Bugzilla 20199: std.math.frexp がCTFE可能となりました。
  • Bugzilla 20200: std.math.isPowerOf2 が浮動小数点数に対してCTFE可能になりました。
  • Bugzilla 20201: std.math.scalbnpure になりました。
  • Bugzilla 20202: std.math.signbit がCTFE可能となりました。
  • Bugzilla 20203: std.math.copysign がCTFE可能となりました。
  • Bugzilla 20242: BitArray のコンストラクタは入力値を変更しないべきです。

DUB変更点

  • LDCにおけるクロスコンパイルのサポートを改善しました。
  • Lint コマンドを追加しました。
  • セマンティックバージョニングにおける "^" の指定を追加しました

注目トピック

言語・コンパイラ変更点

強化: is式の推論改善

is式の推論が少し賢くなりました。
Change Logの抜粋ですが、以前は通らなかった以下の判定が通るようになります。

static assert(is(shared(const int) U == shared U) && is(U == const int));
static assert(is(shared(inout int) U == inout U) && is(U == shared int));

ランタイムにも Unconst の追加という強化があるので、このあたりの推論と何かつながりがあるのかもしれません。
いずれにしてもメタプログラミングが捗りそうです。

強化: template mixin 中の extern(C) 宣言の変更

Change Logの例から一部抜粋ですが、要するに「WebAssemblyのエントリポイントをよろしく生成するテンプレートを書きたい」という要望に応えるための強化のようです。

エントリポイントをテンプレート化する例
// library code
mixin template WasmEntryPoint() {
    extern(C) export void _start() {
        // boilerplate code
    }
}

// application code
mixin WasmEntryPoint;

static assert(_start.mangleof == "_start");

こういった取り組みも行われているということで、今後WebAssembly関連のライブラリ強化も期待できそうですね!

改善: lazyな引数が delegate に変換可能になります。

lazy というのは関数引数の修飾子で、その引数の評価が使われるときまで遅延される、というものです。

たとえばフラグに応じて処理をするか切り替えるとき、「使わないかもしれない値を先に計算して用意しておく」というのはできれば避けたいですよね。

lazy を使うと以下のように書くことで遅延評価になります。

// lazy引数で遅延評価
void times(int n, lazy string message) {
    while (n--)
        writeln(message);
}

// 繰り返し回数は実行時ゼロになることを想定
int n = 0;
int days = 10;
string s = "days";
string m = "later";

// formatの部分はlazyになっているので1度も評価されない
n.times(format!"%d %s %s"(10, s, m));

これを lazy なしに実現しようと考えた場合、 string ではなく string delegate() として、以下のようになるでしょうか。

void times(int n, string delegate() message) {
    while (n--)
        writeln(message());
}

これは lazy に対して内部的に行われていることとほぼ同じなのですが、表現の分かりやすさから lazy キーワードが導入されています。
逆に中身を知ってしまうと、「元々 delegate と変わらないのだから変換できても良いだろう」ということで改善された格好になります。

実際に変換するには以下のようになります。

void test(lazy string t)
{
    string delegate() dg = &t; // アドレスを取るイメージで変換できる
    string s = dg();
}

ちなみにこれをキャストで変換しようとするとエラーになるので注意してください。

互換性などの問題があるのかもしれませんがちょっと思いつかず、実際に問題になるようなケースをご存知の方がいれば教えてください。

ランタイム変更点

強化: core.atomicatomicFetchAddatomicFetchSub を追加

今回追加されたのはC++に元々ある std::atomic::fetchAdd 等にあたる関数です。

機能としては、既存の atomicOp をそれぞれ + または - 演算子で実行してアトミックに置き換え、元の値を返す、というものになります。
(既存の atomicOp は値を置き換えてその値を返すため、変更前の値は取得できません)

サンプルは以下のようになります。

import core.atomic;

shared x = 10;
auto y = atomicFetchAdd(x, 10);

assert(x == 20);
assert(y == 10);

こちら、前回9月のリリースで cas のオーバーロードや atomicExchange の追加がありましたが、今回もその流れで強化があったようです。

こういった関数の追加で使い勝手が良くなって、非同期のプログラムが気楽に書けるようになるのはありがたいですね!

ライブラリ変更点

std.math におけるCTFE強化

今回複数の関数がCTFEに対応しました。
使う頻度が少ない関数もあるようですが、それなりに数があるのでかなり目を引きます。

ちなみにざっくり機能などまとめると以下の通りで、かなりコアな部分までカバーされた印象です。

  • scalbn
    • scalbn(x, n)x * (2 ^^ n) を求めます。
  • isSubnormal
    • isSubnormal(x)x が非正規数かどうかを判定します。
  • isNormal
    • isNormal(x)x が通常の数(NaNやinfinity、0または非正規数でない)かどうかを判定します。
  • frexp
    • frexp(x, exp) で浮動小数点を指数部と仮数部に分解します。戻り値が仮数部、 exp が指数部になります。
  • isPowerOf2
    • isPowerOf2(x)x が2のべき乗かどうかを判定します。
  • signbit
    • signbit(x)x の符号ビットを取得します。負数なら1、正の数なら0になります。
  • copysign
    • copysign(a, b) で、値は a 、符号は b と同じになる値を求めます。

DUB変更点

強化: LDCのクロスコンパイルに対応

LDC 1.18.0でクロスコンパイルに対応したのを受けて、dubのビルドにおける --arch にLDCの -mtriple と同じ値が指定できるようになりました!

これでWindowsからLinuxバイナリを出力できたりするほか、WebAssemblyのビルドやAndroid関連のビルドをdubで行えるようになると思われます。(まだ実験不足です)

具体的に -mtriple に指定できる値は以下を参照してください。

ちなみに主要なプラットフォームの例を挙げると以下のような感じです。

プラットフォーム mtriple
Linux x86_64 with glibc x86_64-linux-gnu
macOS x86_64-apple-darwin16.7.0
Windows x64 x86_64-windows-msvc
Android ARMv7-A armv7a-unknown-linux-androideabi
32-bit WebAssembly wasm32-unknown-unknown-webassembly

強化: lint コマンドの追加

シンタックスやコメントの有無をチェックできる lint コマンドが追加されました。

dubプロジェクトのトップで dub lint とすることで DScanner を使った構文チェックとスタイルチェックを行うことができます。

見つけた警告によってリターンコードが1になったりするので、CIに組み込むことで継続的なチェックが可能です。

また、解析結果をJSONで出力する --report というフラグもあるため、これを解析すれば何かを活かせるかもしれません。

非推奨または廃止される機能

今回は foreach における変数宣言の shadowing が廃止されるのみです。
追加で非推奨になる機能はありません!

通常の for ループではshadowingがエラーになるため、同じ問題で引っかかるケースは稀かと思われます。

また以前からずっと非推奨だったので、警告に気を配っていれば影響を受けることはないと思います。

int n;
foreach (i; 0 .. 100) {
    int n = i * 10;
    writeln(n);
}

まとめ

修正された不具合もそれなりにありますが、求められた機能の追加を中心にツール周りが整えられた印象のリリースです。

また、「新たに非推奨になった機能等がない」というのは、「Breaking changes」という見出しが毎バージョン踊っていたころと比べて非常に印象的です。

少し前から不評な機能を消すことに終始していたのもあり、今回のリリースが1つの節目なのかと思われます。

というわけでリリースのまとめは以上です。

次は年明け元旦予定のリリースを期待して待ちつつ、今後リリースされるであろう大規模機能強化にも注目したいと思います!

(アドベントカレンダーが近いので、今年話題になったネタはある程度そちらでまとめたいと思います)

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?