D言語の更新まとめ 2023年12月版（dmd 2.106.0）

# はじめに

D言語の公式コンパイラである dmd が更新され、最新バージョンである `2.106.0` が 2023/12/01 にリリースされました。

今回は前回からほぼ2ヶ月でのリリースで、コンパイラ周りの強化改善とDUBの強化が目玉になっているようです。
今回も一通りの内容ご紹介していきます。

より細かい内容は下記リンクからChangeLogをご覧ください。

- ChangeLog
    - https://dlang.org/changelog/2.106.0.html

また、前回である2月版のリリースまとめは以下になります。

- D言語の更新まとめ 2023年8月版（dmd 2.105.0）
    - https://qiita.com/lempiji/items/badaff4d08f544864488

# 変更点目次

## コンパイラ変更点

- `catch` 節は、`const` または `mutable` な例外のみを受け付けるようになりました。
- C++ヘッダー生成が改善されました。
-  `enum` ストレージクラスを持つ関数は、現在非推奨となりました。（エラーだったものが非推奨に戻されました）
- コンパイラに `-nothrow` スイッチが追加されました。
- Intel CET（Control-flow Enforcement Technology）のIBT（Indirect Branch Tracking）保護がサポートされました。
- DIP1000による`scope class`インスタンスの生成時に、非スコープコンストラクタを使用することは `@system` のみ可能になりました。
- グローバル `const` 変数は、非 `shared static this` の静的コンストラクタからは初期化できなくなりました。
- グローバル変数として連想配列で初期化できるようになりました。
- `_d_newarray{U,T,iT}` はテンプレートに変換されました。

### 改善点
* Bugzilla 5445: DMDはHOMEディレクトリにある".dmd.conf"を探しません。
* Bugzilla 10532: `static foreach` の時に到達不能な文の警告を抑制します。
* Bugzilla 11070: `switch` 式で宣言文を許可します。
* Bugzilla 15752: 不正な連想配列空値の割り当てに対するより良いエラーメッセージを出力します。
* Bugzilla 20522: 未定義の変数によって引き起こされる到達不能な文の警告を抑制します。
* Bugzilla 21520: dmdはNO_COLOR環境変数を尊重しません。
* Bugzilla 21852: -verrors=contextを使用すると、Locのフォーマットされた1行エラーがコンテキストを出力するようになります。
* Bugzilla 23958: ImportC: 未定義の識別子 `__builtin__sprintf_chk`
* Bugzilla 24060: "Cannot create instance of abstract class" エラーの改善
* Bugzilla 24084: コンパイラに `-nothrow` スイッチを追加
* Bugzilla 24173: ImportCにMicrosoftのiNN整数リテラルサフィックスを追加

## ランタイム変更点

### 変更点
- 4つの `core.memory.GC` 関数が `@safe` とマークされました。


## ライブラリ変更点

### 変更点
- `etc.c.odbc` の廃止が取り消され、非Windowsシステムで再度使用が可能になりました。
- `isInputRange` はオプションの要素型を受け取るようになりました。
- `std.traits` に `Unshared` が追加されました。

### 改善点
- Bugzilla 24082: Int128.toStringを追加し、std.formatをサポートします。
- Bugzilla 24142: Int128を整数型および浮動小数点型にキャストできるようにします。

## DUB変更点
- `dub build` に `--deep=` オプションが追加されました。
- `dub describe` に `default-config`、`configs`、`default-build`、`builds` のデータが追加されました。
- `dub init` に、パッケージ形式とライセンスの選択メニューが追加されました。
- DUBに `--recipe=` スイッチが追加されました。

# 注目トピック

## 言語・コンパイラ変更点

### コンパイラに `-nothrow` スイッチが追加されました。

コンパイラに `-nothrow` スイッチが新たに追加されました。今回の強化の中でもやや異色の強化と言えるかもしれません。

D言語(に限らず多くのプログラミング言語)のコンパイラでは、例外(Exceptions)を投げることを好まず、エラー処理に別の方法を用います。これは多くの場合、例外処理の処理コストが重いこと、例外処理のサポートだけでパフォーマンスが劣化し得る、とにかく性能を改善するためです。

例外をサポートすること自体のコストというと、例えば、RAII（Resource Acquisition Is Initialization）オブジェクトのためのスタックアンワインダーの追加や、`try-catch` 境界を越える際に起きるさまざまな最適化の阻害などがあります。これらのコストは、例外が一度も投げられない場合(要はエラーにならず正常に処理が終了する場合)でも発生します。

そこで、大規模で最適化が重要なプロジェクトでは、プロジェクト内の全てのコードに `nothrow` 修飾子を適用することで対処を試みることがあります。これは非常に労力を要する作業です。特に、モジュールのトップに `nothrow:` を記述しても、クラスや構造体のメンバ関数には影響を与えないため、`class`や `struct` ごとに `nothrow:` を繰り返さなければならないという問題があります。

この問題を解決するために、今回 `-nothrow` スイッチが導入されました。このスイッチを使用すると、コンパイラはスタックアンワインダを追加せず、様々な最適化を有効にします。この機能は以前から `-betterC` コードには存在していましたが、この変更により通常のDコードでも利用可能になります。

`-nothrow`スイッチを使用することで、セマンティック解析には影響を与えず、コード生成のプロセスのみが変更されます。このスイッチはネームマングリングにも影響しません。

開発者は、このスイッチを使って、例外処理が実行可能ファイルのサイズやパフォーマンスにどのような影響を与えるかを容易に評価できます。特に例外を投げないコードのパフォーマンス改善に興味がある場合は、非常に有用です。

とはいえ、実際例外が発生するコードも多数あると思いますので、まずは例外処理によってどれくらい影響があるのか調べる目的で使うことになると思われます。
`-nothrow`スイッチの追加によってこういった調査が行えるようになるので、今後はより高速なプログラムを開発できるようになるかもしれませんね。


### Intel CET（Control-flow Enforcement Technology）のIBT（Indirect Branch Tracking）保護がサポートされました。

今回の注目トピック、IntelのCET（Control-flow Enforcement Technology）におけるIBT（Indirect Branch Tracking）保護のサポートです。

IntelのCETは、プログラムの制御フローを攻撃者が不正にリダイレクトするのを防ぐための技術です。IBTは、特に攻撃者が間接分岐を意図しない場所に送るのを防ぎます。
参考: https://gihyo.jp/article/2022/11/daily-linux-221107

IntelのIBTは、コンパイラが特別な命令（endbr32およびendbr64）を発行することを期待しており、IBTをサポートしていない古いプロセッサではこれらの命令はnop(何もしない)命令と同等になります。そのため、IBTがアクティブな状態でコンパイルされたプログラムは、任意のx86プロセッサで互換性があり、対応しているプロセッサ上であれば保護されます。

DMDでこのIBT保護を有効にするには、コンパイラに `-fIBT` フラグを渡す必要があります。このフラグを渡すと、コンパイラはIBT用の命令発行を自動的に追加します。ただし、インラインアセンブラを使用する場合は注意が必要です。コンパイラはインラインアセンブラ内でのIBTまでは処理しません。

また、Dプログラム内でIBTが有効化されているかどうかを確認するには、`getTargetInfo`トレイトを以下のように使用します。

```d
// IBTがアクティブな場合
static assert(__traits(getTargetInfo, "CET") == 1);  // CET == 1 はIBTがアクティブであることを示す

// IBTがアクティブでない場合
static assert(__traits(getTargetInfo, "CET") == 0);  // CET == 0 はIBTがアクティブでないことを示す
```

プログラムのセキュリティに興味がある開発者は、この新機能の活用を検討してみてください。

### グローバル変数として連想配列で初期化できるようになりました。

これまでのD言語では、グローバル変数を連想配列で初期化するには、モジュールのコンストラクタやenumを使用する必要がありました。しかし、2.106.0の更新により、連想配列を直接グローバル変数として初期化できるようになりました。

```d
immutable string[string] table = ["key": "value"]; // shared static this()で初期化したり、enumにしていた。

void main()
{
    assert(table["key"] == "value"); // そのまま使えるようになった。
}
```

このコードでは、`table`というグローバル変数を連想配列で初期化し、`main` 関数内でその値を検証しています。特に言うこともありませんが、こういった簡便な記述が可能になりました。

ただし、連想配列のキーまたは値の型に `toHash`、`opEquals`、または `~this` メソッドが定義されている場合、これらのメソッドはコンパイル時に呼び出すことが可能である必要があります。実行時のみにデストラクタが実行されるようにするために、`if (!__ctfe)` という記述で分岐する必要があるかもしれません。今後のアップデートで、このような回避策が不要になる可能性もあります。

今回の強化によって、コードの記述がよりシンプルになり、開発プロセスもよりスムーズになると期待されます。引き続き便利に使ってきましょう。

### `_d_newarray{U,T,iT}` はテンプレートに変換されました。

こちら、D言語の配列生成における内部実装の話です。
配列生成に関わる `_d_newarray{U,T,iT}` などの内部関数群が大きく改善されました。これらの関数は、配列のメモリー割り当てと初期化を担う重要な役割を果たしています。具体的には、以下の変更が行われました。

簡単なコード例ですが、配列 `S[] s = new S[10]` の生成は、以下のように変更されます。
```d
S[] s = _d_newarrayT!S(10);
```

新たなテンプレートは、`core.internal.array.construction`に追加され、`core.internal.array.utils`には`__arrayClearPad`、`__arrayAlloc`、`__arrayStart`、`__setArrayAllocLength`のテンプレートが実装されています。
内部的に色々な操作があるためこのような関数群が整備されているわけですが、今回の強化で配列の扱いがより柔軟で効率的になります。

この変更は随分前から取り組まれていたと思うのですが、今回正式に入りました。
長らく検討された機能が入ったという意味で、大きな前進を意味していると思います。


## ランタイムの変更点

### 4つの `core.memory.GC` 関数が `@safe` とマークされました。

特に言うこともないのですが、以下の4つの関数が `@safe` で修飾されました。つまり、安全になりました。

- `GC.enable`
- `GC.disable`
- `GC.collect`
- `GC.minimize`

個人的に何でも1回は `@safe:` と書いておきたいタイプきたい人としては非常に助かる気がします。

## ライブラリ変更点

### `etc.c.odbc` の廃止が取り消され、非Windowsシステムで再度使用が可能になりました。

どれほどの方が使われているか存じないのですが、 `etc.c.odbc` というライブラリの扱いに重要な方針変更がありました。

#### ODBC（Open Database Connectivity）とは？

ODBCは、様々なデータベースシステムへの接続を統一的な方法で提供するAPIの標準です。この標準により、異なるデータベース間でのデータのやり取りが容易になります。Windowsだけでなく、LinuxやmacOSなど、他の主要なプラットフォームでもサポートされています。

D言語の標準ライブラリには元々このためのモジュールが存在しており、ODBCサポートがあったわけです。
（通常、各DBに向けて最適化されたクライアントもまた提供されていたりするわけですが…）

#### `etc.c.odbc`の廃止予定の取り消し

以前のdmdバージョンにおいて、`etc.c.odbc` バインディングは廃止予定とされており、その機能は `core.sys.windows.odbc` に委譲されていました。しかも、`core.sys.windows.odbc` に含まれるバインディングは `version(Windows)` 指定がされており、非Windowsプラットフォームでの使用が困難でした。

この問題に対処するために、dmd 2.106.0では `etc.c.odbc` のバインディングが廃止予定から外され、非Windowsプラットフォームでの使用が再び可能になりました。これはODBCが全主要プラットフォームでサポートされていることを考慮した変更であり、D言語の幅広い利用の証左であると言えるかと思います。

この変更により、D言語の開発者はWindows以外のプラットフォームでも`etc.c.odbc`を利用してデータベースにアクセスすることが可能になります。このことは、D言語によるアプリケーションが異なるプラットフォームでも動作するようにコードベースの移植性を高めることにつながります。


### `isInputRange` はオプションの要素型を受け取るようになりました。

まず、`isInputRange`がどのような関数かを理解しましょう。D言語において、`isInputRange`は範囲（コレクションやシーケンスなど）が特定の条件を満たしているかをチェックするテンプレート関数です。この関数は、いわゆるレンジが反復可能であるかどうか（例えば、`foreach`ループで使用できるかどうか）を判断するために使用されます。

今回の変更により、`isInputRange`関数に新しいテンプレート引数が追加されました。このオプションの2番目のテンプレート引数によって、プログラマーは範囲の要素型を指定できるようになります。具体的には、この引数が `void` でない場合、範囲の要素の型が追加された引数の型と同一である（constを除いて）場合にのみ、関数は `true` を返します。

例えば、`isInputRange!(int[], const(int))` の場合、 `int` 型の配列が `const(int)` 型と互換性があるため`true`を返します。
しかし、`isInputRange!(int[], string)` の場合は、`int` 型の配列と `string` 型は互換性がないため `false` を返します。

```d:イメージ
static assert(isInputRange!(int[], const(int))); // 要素のintはconst(int)? => is(int : const(int))
static assert(isInputRange!(int[], string)); // 要素のintはstring? => !is(int : string)
```

この変更によって、コンパイル時により精密な型チェックを行うことができるようになります。これは、プログラムの安全性を高め、意図しない型のデータが範囲内で使用されるのを防ぐのに役立ちます。
例えば、数値の配列に対して文字列を操作しようとする場合、この新しい `isInputRange` のチェックを用いると簡単に `static assert` を使った検証が書けるため、謎の型不一致のエラーメッセージを回避したりできます。

この変更は、D言語が提供する強力な型システムをさらに有効活用する手段をプログラマーに提供します。今後の開発で親切なエラーメッセージを出したい場合など、積極的に活用していきたいですね。


### `std.traits` に `Unshared` が追加されました。

今回追加された`Unshared`は、プログラマが共有状態(`shared`)のデータをより柔軟に、かつ安全に扱えるようにするための機能強化です。

`Unshared`は、`std.traits`モジュールに新たに追加された機能で、型から外側の`shared`修飾子を取り除くために使用されます。これにより、プログラマは共有データに対する操作をより細かく制御することが可能になります。

公式のサンプルが分かりやすいので引用します。

```d
static assert(Unshared!(shared int) == int);
static assert(Unshared!(shared(int[])) == shared(int)[]);
```

この例は、`Unshared`がどのように動作するかを示しています。
最初の例では、`shared int` から `shared` を取り除くと単なる `int` になります。
次に、`shared(int[])`（sharedがintの配列全体にかかっている）から、配列の各要素が共有される状態（`shared(int)[]`）に変換されます。
要するに、表面的な `shared` を1階層分だけ外す、という操作になっています。

なぜこの機能が追加されたのかと考えると、元々 `shared` を外すには `cast()sharedObj;` のような空のキャストを書く必要があってわかりづらい、という話があるためかと思います。（型レベルで操作する分には `is` 式を使ったりする方法もありますが）

今回追加された `Unshared` ですが、既存の類似機能として `Unconst` や `Unqual` といったものがあります。
`Unconst` は `const`, `immutable`, `inout` を取り除き、`Unqual`は型から全ての修飾子を取り除きます。
合わせて覚えておくとメタプログラミングが捗るかと思います。

## DUB変更点

### `dub build` に `--deep=` オプションが追加されました。

今回DUBの `dub build` コマンドに新たに追加された `--deep=` オプションは、スタティックライブラリ(staticLibrary)の依存関係にある全てのライブラリをビルドすることを可能にします。従来では、DUBの設定ファイルが存在するルートディレクトリにあるライブラリのみがビルドされるという挙動でしたが、この新オプションにより、一括でのビルド管理が可能となります。要するに、作業効率の向上に貢献する新機能です。

使用方法は難しくありません。フラグを付けるだけです。
このコマンドを実行すると、プロジェクトの依存する全てのスタティックライブラリがビルドされます。

```bash
dub build --deep
```

様々な依存関係を持つ静的ライブラリを作っている場合には、大変便利な機能になるかもしれません。
順番にビルドしている、結局ビルドスクリプトを書いている、といったケースがあれば解決するかもしれませんのでぜひ試してみてください。


### `dub describe` に `default-config`、`configs`、`default-build`、`builds` のデータが追加されました。

`dub describe`コマンドにいくつかの新たな機能が追加され、パッケージの管理および情報提供が強化されました。
ただし、これはIDE向けの情報を提供する側面が強いコマンドなので、日ごろ使う人は多くないかもしれません。

今回の強化により、追加で取れるようになった情報が4つあります。

- **`default-config`:** これは文字列で、特に設定が指定されなかった場合にDUBが選択する`--config`設定を表します。例えば、`dub build`コマンドを単純に実行した場合にDUBがどの設定を選ぶかがこの値になります。
- **`configs`:** これは、利用可能なすべての設定のリストを含みます。このリストには、デフォルトで生成されるアプリケーションやライブラリ、またはレシピで手動で指定された設定が含まれます。
- **`default-build`:** これは文字列で、特にビルドタイプが指定されていない場合にDUBが選択する`--build`のビルドタイプを表します。現時点では、この値は常に"debug"です。
- **`builds`:** これは、利用可能なすべてのビルドタイプのリストを含みます。内蔵されているビルドタイプに加えて、カスタムで定義されたビルドタイプもこのリストに含まれます。

これらの新機能は、開発者が必要とする情報をIDEにより多く伝えたりすることを目的としています。ぜひとも今後の開発環境の進歩に活用してもらいたいと思う次第です。


### `dub init` に、パッケージ形式とライセンスの選択メニューが追加されました。

DUBの`dub init`コマンドが強化され、ライセンス選択などのプロンプトが出るようになりました。
百聞は一見に如かずなので、実行してみるか下記実行例をご確認ください。

__パッケージ形式とライセンスの選択__

1. `dub init`コマンドがアップデートされ、新しいプロジェクトを始める際にパッケージ形式（sdlまたはjson）とライセンスを選択する新機能が追加されました。これは、プロジェクトの初期セットアップをより柔軟にし、開発者が自分のニーズに合ったプロジェクト構成を簡単に定義できるようにするためのものです。（あとデフォルトをそろそろSDLにしてほしい）

__選択できるライセンス__

選択できるライセンスには、BSD、MIT、GPL、Apache、Mozilla、Boostなど、オープンソースコミュニティで広く使用されているものが含まれます。また、プロプライエタリなライセンスを選択するオプションも用意されており、商用プロジェクトに対応しています。(商用プロジェクトがDで書かれた事例はいくつもあります！)

### 実行例

以下は、`dub init`を実行した際の例です。

```console
PS C:\work\articles\dmd-2.106.0> dub init
Select a package recipe format:
1) sdl    2) json
#? [2]: 1
Name [dmd-2.106.0]:
       Error Invalid name 'dmd-2.106.0', names should consist only of lowercase alphanumeric characters, dashes ('-') and underscores ('_').
Name [dmd-2.106.0]: dmd2106
Description [A minimal D application.]:
Author name [lempiji]:
Select or enter an SPDX license-identifier (https://spdx.org/licenses/):
 1) BSL-1.0 (Boost)               8) BSD-
 2) MIT                           9) MPL- (Mozilla)
 3) Unlicense (public domain)    10) EUPL-
 4) Apache-                      11) CC- (Creative Commons)
 5) AGPL-                        12) Zlib
 6) GPL-                         13) ISC
 7) LGPL-                        14) proprietary
? [14]: 2
     Success created empty project in C:\work\articles\dmd-2.106.0
             Package successfully created in .
```

この例では、設定ファイルに `sdl` 形式を選択し、プロジェクト名を `dmd2106` に設定し、MITライセンスを選択しました。（が、LICENSEファイルは作られません。残念。）
使えるプロジェクト名の文字チェックなども行われるので、変に打ち損じることが無くて良さそうです。

ともかく、これで今までよりも新しいプロジェクトが細かい設定をしながらも素早く初期化できるようになります。
どんどんライブラリやアプリを作っていきましょう！


### DUBに `--recipe=` スイッチが追加されました。

通常、DUBはプロジェクトのルートディレクトリにある`dub.sdl`または`dub.json`ファイルをビルド設定のレシピとして使用します。これらのファイルは、プロジェクトの依存関係、ビルドオプション、その他の設定を定義してありますが、新たに追加された`--recipe=`スイッチを使うことで、これらのデフォルトファイルの代わりに別のファイルをビルド設定として指定することができるようになりました。

### 使用例

例えば、ローカル開発環境専用の特別なビルド設定を持つ複数の `dub.json` ファイルがある場合、以下のようにして特定の設定ファイルを選択してビルドを実行できます。

```bash
dub build --recipe=custom-dub.json
```

この機能は、同じディレクトリ内に`dub.sdl`と`dub.json`の両方が存在する場合に、どちらを使用するか選択する際にも便利です。しかし、このような状況は、他のDUBをサポートするツールとの互換性や一般的なユーザーの混乱を招くため、推奨されません。将来的には、このスイッチが指定されていない限り、複数のファイルがあるとエラーとする可能性も検討されています。

## メリットと将来の影響

`--recipe=`スイッチの導入により、設定の管理がより柔軟になります。開発者はプロジェクトごとに異なるビルド設定を容易に切り替えることができ、特定の作業や環境に最適化された設定を用意することが可能になります。大きくなりすぎたファイルの分割などもまた推奨されるかもしれません。

しかし、この新機能の利用には注意も必要です。特に、プロジェクトディレクトリ内に`dub.sdl`と`dub.json`の両方を保持することの潜在的な混乱や、未来におけるエラーにつながる可能性に注意して、慎重に設定を管理していきましょう。


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

今回は、非推奨が1件、廃止が3件で計4件の機能が非推奨および廃止となります。
ただし1件動作が確認できないものがあり、これを除外すると廃止は2件です。

余り影響のないものが多いですが、一部わかりづらいものもありますので一つ一つ解説していきます。

また今後の予定などは以下のページにまとまっていますので、こちらも参考としてみてください。

https://dlang.org/deprecate.html

__非推奨__
-  `enum` ストレージクラスを持つ関数は、現在非推奨となりました。（エラーだったものが非推奨に戻されました）

__削除/エラー__
- グローバル `const` 変数は、非 `shared static this` の静的コンストラクタからは初期化できなくなりました。
- `catch` 節は、`const` または `mutable` な例外のみを受け付けるようになりました。

__未確認__
- DIP1000による `scope class` インスタンスの生成時に、非スコープコンストラクタを使用することは `@system` のみ可能になりました。


### 非推奨 : `enum` ストレージクラスを持つ関数は、現在非推奨となりました。（エラーだったものが非推奨に戻されました）
The error was introduced in 2.105.0.

2.105.0でエラーとされていたものが、なんと非推奨に格上げ？されました。
誰か猛烈に困ったユーザーがいたのでしょうか。今まで前例がなかったと思われ、ちょっと謎です。

見かけたら対処しておくに越したことはないので、前回記事も参照してください。対処方法も含めて記載してあります。
https://qiita.com/lempiji/items/badaff4d08f544864488#%E5%89%8A%E9%99%A4%E3%82%A8%E3%83%A9%E3%83%BC--%E9%96%A2%E6%95%B0%E3%81%AF-enum-%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E6%8C%87%E5%AE%9A%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%8F%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F

### 削除/エラー : グローバル `const` 変数は、非 `shared static this` の静的コンストラクタからは初期化できなくなりました。


バージョン2.106.0以前では、グローバルな`const`変数を非`shared static this`の静的コンストラクタから初期化することが可能でした。しかし、この更新により、そのような初期化はできなくなりました。

仕組みについて少し補足すると、グローバル変数の `const` や `immutable` なデータは、いわゆるスレッドローカルストレージ(TLS)に配置されないため、スレッドごとに異なる値を持つことができません。（本当にグローバルな変数になる）
この特性により、スレッドごとに実行されるスレッドローカルな静的コンストラクタ(`static this() {}`)内でこれらの変数を初期化しようとすると、`const` や `immutable` の意図に反する動作を引き起こす可能性があります。


以下のコードは、古いバージョンのdmdでは許可されていましたが、2.106.0では非推奨またはエラーとなります。

```d
int x;
const int y;
immutable int z;

static this()
{
    x = 1;    // これは変わらず許可されます。
    y = 2;    // 非推奨: const変数を変更することはできません。
    z = 3;    // エラー: immutable変数を変更することはできません（以前から同様）。
}
```

__エラー例__
```
source\app.d(14,5): Deprecation: const variable `y` initialization is not allowed in `static this`
source\app.d(14,5):        Use `shared static this` instead.
source\app.d(15,5): Error: immutable variable `z` initialization is not allowed in `static this`
source\app.d(15,5):        Use `shared static this` instead.
```

この問題に対する解決策は、エラーメッセージにもある通り単なる `static this` から初期化処理を共有（`shared`）静的コンストラクタ（`shared static this`）に移動することです。

```d
const int y;

shared static this()
{
    y = 4;  // OK: グローバルなconst変数の初期化は共有静的コンストラクタから行うだけ
}
```

`Use ... instead.` というメッセージをみかけたら、それに従っておくのが吉となります。


### 削除/エラー : `catch` 節は、`const` または `mutable` な例外のみを受け付けるようになりました。
以下のような `catch` で例外に修飾されているケースがエラーとなりました。

```d
auto e = new Exception("first");
try {
        throw e;
} catch(immutable Exception ie) { // now an error
        e.msg = "second";
        assert(ie.msg == "first"); // would fail
}
```

これは元々2.104.0で非推奨とされていたものがエラーになっただけです。

詳細や対応は以下の記事でも言及していますので、こちら参照ください。
前回記事: https://qiita.com/lempiji/items/badaff4d08f544864488#%E9%9D%9E%E6%8E%A8%E5%A5%A8--catch-%E7%AF%80%E3%81%AFconst-%E3%81%BE%E3%81%9F%E3%81%AF-mutable-%E3%81%AA%E4%BE%8B%E5%A4%96%E3%81%AE%E3%81%BF%E3%82%92%E5%8F%96%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99


# まとめ

DUBの強化、ライブラリ強化、コンパイラ強化、と結構目白押しでした。
ODBCの復活や1回エラーになった問題が非推奨として復活？するなどやや不思議な活動も見られますが、ユーザー利便性に配慮した決断だったのだろうと思います。

いくつか性能に寄与しそうな部分含め、コンパイラスイッチなどは大規模開発だと注目しどころかと思います。
DUBについてもinitが面白い画面になっているので1回見てみることをおすすめします。
そのままライブラリ開発に取り組んでまいりましょう。

さて、この記事もリリースからだいぶ遅れて書いていますが、既に次のリリースが出ている状況でもありますので次の記事も書き進めていきたいと思います。
引き続きよろしくお願いします！