英語版
このページの英語版を見る

D 2.0 FAQ

同じ質問が繰り返し出てくるので、当然すべきことは FAQを用意することだ。

D 1.0 FAQ

C++ FAQ

D 2.0 FAQ

一般的なDに関するFAQ


なぜ case range 文ではcase X..Y: の構文を使用しないのか?

case range statementを参照。

その用法は次のようになる。

  1. case X..Y:
  2. foreach(e; X..Y)
  3. array[X..Y]
ケース (1) は (2) および (3) とは非常に異なる意味を持つ。 (1) は Y を含み、(2) および (3) は Y を除外する。 非常に異なる意味を持つということは、非常に異なる構文を持つべきであるということだ。


共有が提供する保証とは何だろうか?

共有とは、複数のスレッドがデータにアクセスできることを意味する。保証されるのは、 共有されておらず、不変でもない場合、現在のスレッドのみがデータにアクセスできるということだ。

共有とは、複数のスレッドがデータにアクセスできることを意味する。保証されるのは、 共有されておらず、かつ不変でもない場合、現在のスレッドのみがデータにアクセスできるということだ。

共有と同期化にはどのような関係があるのか?

共有と同期化にはどのような関係があるのか?

共有されているデータのみが同期可能である。スレッドローカルのデータを同期する意味はない 。

共有されたデータのみが同期可能である。スレッドローカルなデータを同期しても意味がない。


共有とメモリバリアの関係は?

現在、コンパイラは共有変数の周りにメモリバリアを挿入しない。


非共有から共有へのキャストのセマンティクスとはどのようなものか?

同じデータへの他の非共有参照がないことを確認する。

同じデータへの他の非共有参照がないことを確認する。


共有から非共有へのキャストの意味は?

同じデータに対する共有参照が他にないことを確認する。

同じデータに対する共有参照が他にないことを確認する。


なぜ大きな静的配列が実行ファイルのサイズを肥大化させるのか?

宣言を考えると、

char[1024 * 1024] arr;
実行可能ファイルのサイズは1メガバイト分大きくなる。C言語では、 xml-ph-0000@deepl.internalがBSSセグメントに格納されるため、 このようにはならない。D言語では、xml-

実行可能ファイルのサイズは1メガバイト分大きくなります。C言語では、arr はBSSセグメントに格納されるため、このようにはなりません。 D言語では、arr はBSSセグメントに格納されないため、

以下はBSSに配置される。

__gshared byte[1024 * 1024] arr;

byteは0で初期化され、__gshared はそれを グローバルデータに置く。

floatdoublerealの静的配列についても同様の問題がある。 これらは0ではなくNaN(非数値)値に初期化される。

この問題に対処する最も簡単な方法は、配列を静的に割り当てるのではなく、 実行時に動的に割り当てることである。


なぜDという名前なのか?

当初の名称は Mars Programming Language であった。しかし、私の友人たちは Dと呼び続け、私もDと呼び始めた。 DがCの後継であるという考えは、少なくとも1990年代まで遡る。

当初の名称は「Marsプログラミング言語」であった。しかし、私の友人たちは それを「D」と呼び続け、私もいつの間にか「D」と呼ぶようになっていた。 DがCの後継であるという考えは、少なくとも1988年まで遡る。 この スレッドのように。


名前を変えてもらえないだろうか? Dは検索エンジンで検索するのが難しい。

いいえ。ご不満は理解しているが、現時点での名称変更は遅すぎる。 「dlang」、「d programming」、「d language」、または「d programming language」を使用することをお勧めする。

いいえ。ご不満なのは理解できますが、現時点での名称変更はすでに手遅れです。 検索用語として「dlang」、「d programming」、「 d language」、または「d programming language」を使用することをお勧めします。そうすれば、 はるかに優れた検索結果が得られるはずです。

一般に公開されているDコードのほとんどは、最初のコメントとして「// Written in the D programming language」と記述されている。


DのLinux版はあるか?

はい、DコンパイラにはLinux版が含まれています。

はい、DコンパイラにはLinux版が含まれています。


GNU版Dはあるか?

はい、 gdc - GCC との D フロントエンド。

はい、 GCC用のDフロントエンドであるgdcがある


CPU X用のDコンパイラを自分で書くにはどうすればよいか?

バートン・ラドンが バックエンドを 作成している。 参考にすることができる。

バートン・ラドンズがバックエンドを 作成している。 参考にすることができる。


D用のGUIライブラリはどこで入手できるか?

DはC関数を呼び出すことができるため、Cインターフェイスを持つGUIライブラリはすべて Dからアクセス可能である。さまざまなD GUIライブラリおよび移植版は、 D wikiで見つけることができる。


D用の統合開発環境(IDE)はどこで入手できるか?

Dをサポートするエディターおよび IDEの一覧は、D wikiに掲載されている。 "editor"エディター


なぜDにprintfがあるのか?

printf はDの一部ではなく、Cの標準ランタイムライブラリの一部であり、 Dからアクセスできる。 Dの標準ランタイムライブラリには

printf はDの一部ではなく、Cの標準ランタイムライブラリの一部であり、 Dからアクセスできる。 Dの標準ランタイムライブラリには、 std.stdio.writefln printfと同等の機能を持つ が、はるかに使いやすい。


Dはオープンソースですか?

Dの dmdD コンパイラとランタイムライブラリは、完全にオープンソースであり、 Boostライセンス1.0を使用している。 すべての開発は github上で 公開されている。 gdc および ldcDコンパイラ は、GCCまたはLLVMバックエンドとDMDフロントエンドを備えている。


標準ライブラリはなぜブーストライセンスを使用しているのか?なぜパブリックドメインではないのか?

ほとんどの管轄区域ではパブリックドメインの概念が使用されているが、一部の 国(日本など)では使用されていない。 ブーストライセンスは この問題を回避する。他のほとんどのオープンソースライセンスとは異なり、バイナリ形式で配布されるライセンステキストにライセンステキストを含めることを要求しないため、このライセンスが選択された。


なぜswitch文でフォールスルーしないのか?

多くの人々が、switch文のケース間にブレークを入れることを要求している。 Cの動作では、黙ってフォールスルーするため、 多くのバグの原因となっている。

多くの人々が、switch文のケース間にブレークを設けることを要求している。 C言語では、黙ってフォールスルーする動作が 多くのバグの原因となっている。

。 D2では暗黙的なフォールスルーは許可されていない。 フォールスルーの意図を明示的に示すために goto case; ステートメントを追加する必要がある。

D2では暗黙のフォールスルーは禁止されている。 フォールスルーの意図を明示するには、 goto case;文を追加する必要がある。

さらに、break 文を暗黙的なものにするという要望もあった。 Dがこれを変更しない理由は、整数の昇格規則と演算子の優先順位規則を同じにしたのと同じ理由による。 つまり、Cと同じように見えるコードを同じように動作させるためである。微妙に 異なる意味論があった場合、非常に厄介なバグを引き起こすことになる。


なぜJavaではなくDを使うべきなのか?

Dは目的、哲学、現実においてJavaとは異なる。 この比較を参照。

DはJavaとは目的、哲学、現実において明確に異なる。 この比較を参照。

Javaは「一度書けばどこでも動く」ように設計されている。Dは 効率的なネイティブシステムアプリケーションを書くために設計されている。DとJavaは「 ガベージコレクションは良いものであり、多重継承は良くない」という考え方を共有しているが、 異なる設計目標を持つことで、両言語はまったく異なる使用感となっている。


C++はSTLで文字列などをサポートしていないのか?

C++標準ライブラリには、文字列、動的配列、連想配列、境界チェック付き配列を扱うためのメカニズムがある。

もちろん、これらの機能はライブラリを使用することで実現できる。 特定のコーディング規約に従うなど、 しかし、 オブジェクト指向プログラミングはCでも可能である(実際に行われている)。 C++でないとできないというのは、不自然ではないだろうか。

もちろん、これらの機能はライブラリを使用すれば、 特定のコーディング規約に従うなどして実現できる。しかし、 オブジェクト指向プログラミングはCでも可能だ(実際、そうしてきた)。 最もシンプルなBASICインタプリタでサポートされている文字列のようなものが、 サポートするために非常に大規模で複雑なインフラストラクチャを必要とするのは、 不自然ではないだろうか? STLの文字列型の実装は、テンプレートの高度な機能のすべてを使用して、 テンプレートの高度な機能のすべてを使用して、2000行以上のコードを必要とする。 これがすべて正しく動作していると、どれほどの確信が持てるだろうか。 もし正しく動作していない場合、それを修正するにはどうすればよいのか。 エラーが発生した場合、どうすれば その不可解なエラーメッセージに対処できるのか。

Dの文字列の実装はシンプルでわかりやすい。 使い方に疑問の余地はほとんどなく、メモリリークの心配もない。 エラーメッセージは的を射ており、

Dの文字列の実装はシンプルでわかりやすい。 使い方に迷うことはほとんどなく、メモリリークの心配もない。 エラーメッセージは的を射ており、期待通りに動作しているかどうかを確認するのは難しくない。


C++でガベージコレクションを追加ライブラリで行うことはできないのだろうか?

はい、私も使っています。ただし、これは言語の一部ではなく、 動作させるには言語を多少改造する必要があります。 C++でgcを使用するのは標準的な方法ではありません。

はい、私も使っています。ただし、これは言語の一部ではなく、 言語を多少改造する必要があります。 gcをC++で使用するのは、標準的なC++プログラマーやカジュアルなC++プログラマー向けではありません。 D言語のように言語に組み込むことで、 日常的なプログラミング作業に実用的なものとなります。

GCを実装するのはそれほど難しいことではない。ただし、 より高度なものを構築する場合を除く。しかし、より高度なものを構築するというのは、 より優れた最適化ツールを構築するようなものであり、言語は依然として100%正確に動作する。

GCの実装もそれほど難しいものではない。ただし、高度なものを構築する場合は別だ。 しかし、高度なものを構築するというのは、より優れた最適化機能を構築するようなものであり、 言語は単純な基本的なものであっても100%正しく機能する。プログラミングコミュニティは、 仕様書のどの部分が実装されているかよりも、生成されるコードの品質を競い合う複数の実装によって より良く機能する。


C++でユニットテストを行うには、アドオンライブラリが必要だろうか?

もちろん。まずは試してみて、それからD言語でどうやるか比較してみよう。 言語に組み込むことでどれほど改善されるかはすぐに明らかになるはずだ。

ポータブルな言語にアセンブリ言語の文がある理由とは?

asm文を使用すると、アセンブリコードをD関数に直接挿入することができる 。アセンブラのコードは、当然ながら本質的に移植性のないものである。Dは システムアプリケーションの開発に役立つ言語として意図されている。 システムアプリケーションは、ほぼ例外なくシステム依存のコードを含んでいる 。インラインアセンブラもそれほど違いはない。インラインアセンブラは、 特別なCPU命令へのアクセス、フラグビットへのアクセス、特別な 計算状況、コードのスーパー最適化などにおいて役立つ。

Cコンパイラにインラインアセンブラが搭載される前は、私は外部アセンブラを使用していた。 多くの異なるバージョンのアセンブラが存在し、 ベンダーはアセンブラの構文を変更し続け、異なるバージョンには多くの異なるバグがあり、 コマンドラインの構文さえも変更され続けていた。 つまり、ユーザーは アセンブラを必要とするコードを確実に再構築することができなかったのだ。インライン アセンブラは信頼性と一貫性を提供した。


80ビット浮動小数点演算の利点とは何だろうか?

精度が高ければ、特に多数の小数の実数を足し合わせる場合など、浮動小数点演算をより正確に行うことができる。 インテル浮動小数点ユニットを設計したカハン教授は、 このテーマについて非常にわかりやすい論文を 書いている

D言語で構造体や共用体を匿名で作成するにはどうすればよいか?

structstruct
import std.stdio;

struct Foo
{
    union { int a; int b; }
    struct { int c; int d; }
}

void main()
{
    writefln(
        "Foo.sizeof = %d, a.offset = %d, b.offset = %d, c.offset = %d, d.offset = %d",
        Foo.sizeof,
        Foo.a.offsetof,
        Foo.b.offsetof,
        Foo.c.offsetof,
        Foo.d.offsetof);
}

printf()を文字列で動作させるにはどうすればよいか?

C言語では、文字列をprintfで表示する通常の方法は、%sフォーマットを使用することである。
char s[8];
strcpy(s, "foo");
printf("string = '%s'\n", s);
D言語でこれを試みると、以下のように、
string s;
s = "foo";
printf("string = '%s'\n", s);
通常は文字化けするか、アクセス違反が発生する。 原因は、Cでは文字列が0文字で終了していることだ。%s 形式では、0が検出されるまで出力される。 Dでは文字列は0で終了しておらず、サイズは 別の長さの値によって決定される。そのため、文字列は%.*s 形式で出力される。
string s;
s = "foo";
printf("string = '%.*s'\n", s);

期待通りに動作する。 ただし、printfの%.*s は、長さに達するか0が検出されるまで印刷されることを覚えておいてほしい 。そのため、0が埋め込まれたD文字列は 最初の0までしか印刷されない。

もちろん、より簡単な解決策は、 std.stdio.writefln D文字列で正しく動作する


浮動小数点値は、なぜデフォルトで0ではなくNaNに初期化されるのか?

浮動小数点値は、明示的な初期化子が与えられない場合、 NaN(非数値)に初期化される。
double d;   // dはdouble.nanに設定される

NaNには興味深い特性があり、 演算のオペランドとしてNaNが使用されると、結果は常にNaNとなる。したがって、 演算でNaNが使用されると、その出力にもNaNが現れる。 これは、出力にNaNが現れることは、 未初期化変数が使用されたことを明確に示すことを意味する

浮動小数点値のデフォルト初期化子として 0.0 が使用された場合、 その影響は出力では簡単に気づかれない可能性があり、そのため デフォルト初期化子が意図しないものであった場合、そのバグは 認識されないままになる可能性がある。

デフォルトの初期化子値は有用な値であることを意図したものではなく、 バグを明らかにすることを意図したものである。ナンの値は、その役割を十分に果たしている。

しかし、初期化されていない変数が使用された場合、コンパイラが確実にエラーメッセージを表示できるのだろうか? ほとんどの場合、 それは可能だが、常に可能というわけではない。また、コンパイラが実行できることは、 その

しかし、初期化されていない変数が使用された場合、コンパイラが確実にエラーメッセージを表示することはできるのだろうか? ほとんどの場合、 可能であるが、常に可能というわけではない。また、コンパイラが実行できることは、 コンパイラの内部データフロー解析の洗練度に依存する。 したがって、そのようなものに頼るのは移植性のない信頼できないものとなる。

CPUの設計上、整数にはNaN値が存在しないため、 Dでは代わりに0を使用している。NaNのようなエラー検出の利点はないが、 少なくともエラーの結果は

CPUの設計上、整数にはNaN値がないため、 Dでは代わりに0を使用している。NaNの持つエラー検出の利点はないが、 少なくとも意図しないデフォルト初期化によるエラーは一貫性があり、 そのためデバッグが容易になる。


なぜ代入演算子のオーバーロードがサポートされていないのか?

構造体に対する代入演算子のオーバーロードは、D 2.0でサポートされている。


「~」が私のキーボードにない?

PCのキーボードでは、[Alt]キーを押しながら、テンキーの1、2、6のキーを順に押す。 そうすると、'~'文字が生成される。


他のコンパイラで作成したCオブジェクトファイルをリンクすることはできますか?

DMDはOMF(Microsoft Object Module Format)オブジェクトファイルを生成するが、 VC++などの他のコンパイラはCOFFオブジェクトファイルを生成する。 DMDの出力は、DMC(Digital Mars )というC コンパイラと併用するように設計されている。DMCもOMF形式のオブジェクトファイルを生成する。

DMDが使用するOMF形式は、インテルが以前に設計したものをベースにマイクロソフトが定義した形式である。 マイクロソフトは、ある時点で COFFのマイクロソフト定義の派生形を採用するために、これを放棄することを決定した。

同じオブジェクト形式を使用しているからといって、その形式のCライブラリがすべて 正常にリンクおよび実行できるわけではない。 さらに多くの互換性が必要である 。例えば、呼び出し規約、名前の変更、コンパイラヘルパー 関数などである。

同じオブジェクトフォーマットを使用しているからといって、そのフォーマットのCライブラリが 正常にリンクされ実行されるとは限らない。 さらに多くの互換性が必要である。 例えば、呼び出し規約、名前の変更、コンパイラヘルパー "関数、および動作に関する隠れた前提条件などである。DMDが Microsoft COFF出力ファイルを作成した場合でも、 。MicrosoftのコンパイラがOMFを生成していた当時、この問題は数多く発生していた。

オブジェクトファイルのフォーマットが異なるため、 DMDとの動作テストが行われていないライブラリファイルを特定するのに役立つ。そうでない場合、 リンクに成功しても、奇妙な問題が発生する可能性がある。 あるベンダーのコンパイラで作成されたバイナリを、 別のベンダーのコンパイラの出力で動作させるには、専門家の知識が必要だ

とはいえ、DMDのLinux版は、Linuxの標準であるELF形式のオブジェクトファイルを生成する。 また、Linuxの標準Cコンパイラであるgccと連携するように特別に設計されている。

既存のCライブラリを使用できるケースが1つある。 そのライブラリが通常のC ABIインターフェースに準拠したDLL形式の場合だ 。このリンク可能な部分は「インポートライブラリ」と呼ばれる。

既存のCライブラリを使用できるケースが1つある。 そのライブラリが通常のC ABIインターフェイスに準拠したDLL形式の場合である 。このリンク可能な部分は「インポートライブラリ」と呼ばれ、 Microsoft COFF形式のインポートライブラリは、 coff2omf ツールを使用してDMD OMFに正常に変換できる 。


なぜ/foo/g 構文で正規表現リテラルをサポートしないのか ?

理由は2つある。

xml-ph-0000@deepl.internalの構文では、 /が区切りトークンであるため、レキサーとパーサーを分離することが不可能になる。
  1. /foo/g の構文では、 /が区切りトークンであるため、レキシカルパーサーとパーサーを分離することが不可能になる。
  2. すでに3つの文字列型が存在しており、正規表現リテラルを追加すると さらに3つ増えることになる。これはコンパイラ、デバッガ情報、ライブラリの大部分に広がってしまい、 割に合わない。

なぜすべてのDigital Mars プログラムがDに変換されないのか?

複雑なデバッグ済みのアプリケーションを、ある言語から別の言語に翻訳するメリットはほとんどない。 しかし、新しいDigital Mars アプリケーションは Dで実装されている。


for ループではなく foreach ループを使用すべき場合は?

パフォーマンスだけなのか、それとも可読性なのか?

foreach を使用することで、コンパイラが最適化を決定する ようにし、自分で最適化について心配する必要がなくなる。例えば - ポインタとインデックスのどちらがよいか? 終了条件をキャッシュすべきか否か? ループをローテーションすべきか否か? これらの質問に対する答えは簡単ではなく、マシンによって異なる 可能性がある。レジスタの割り当てと同様に、最適化はコンパイラに任せる べきである。

または:
for (int i = 0; i < foo.length; i++)
または:
for (int i = 0; i < foo.length; ++i)
または:
for (T* p = &foo[0]; p < &foo[length]; p++)
or:
T* pend = &foo[length];
for (T* p = &foo[0]; p < pend; ++p)
or:
T* pend = &foo[length];
T* p = &foo[0];
if (p < pend)
{
    do
    {
        ...
    } while (++p < pend);
}
そしてもちろん、size_tとintのどちらを使うべきだろうか?
for (size_t i = 0; i < foo.length; i++)
コンパイラに選んでもらおう!
foreach (v; foo)
    ...

Tがどのような型である必要があるのかさえ知る必要がないことに注目してほしい。これにより、 Tが変更された場合でもバグを回避できる。fooが配列であるか、連想配列であるか、構造体であるか、コレクションクラスであるかさえ知る必要がない。 これは、よくあるフェンスポストバグも回避できる。

fencepostフェンスポスト
for (int i = 0; i <= foo.length; i++)
また、fooが関数呼び出しである場合、一時的なものを手動で作成する必要もなくなる。

また、fooが関数呼び出しである場合、一時的なものを手動で作成する必要もなくなる。

forループを使用する唯一の理由は、ループが通常の形式に適合しない場合のみである。 例えば、 終了条件をその場で変更したい場合などだ。

forループを使用する唯一の理由は、ループが従来の形式に適合しない場合である。 例えば、 終了条件をその場で変更したい場合などだ。


なぜDにはC++と同様にC言語とのインターフェイスがないのか?

D 2.0には C++コードへの限定的なインターフェイスが存在する。

完全なインターフェイスではない理由をいくつか挙げてみよう。

DをC++とインターフェイスさせることは、 C++コンパイラを書くこととほぼ同様に複雑であり、 Dを実装しやすい言語にするという目標を台無しにしてしまう。 C++コードベースをすでに持っている人にとっては、 C++に固執せざるを得ない(他の言語に移行することもできない)。

Dコードが修正不可能と想定される任意のC++コードを呼び出すためには、解決しなければならない多くの問題がある。 この リストは完全なものではなく、関連する問題の規模を示すためのものに過ぎない。

  1. Dのソースコードはユニコードだが、C++のソースコードはコードページ付きのASCIIである。あるいはそうではない。 どちらとも決まっていない。これは文字列リテラルの内容に影響する。
  2. std::stringはマルチバイトのUTFを扱うことができない。
  3. C++にはタグ名空間がある。Dにはない。何らかの名前変更が必要になるだろう。
  4. C++のコードは、コンパイラ固有の拡張機能に依存していることが多い。
  5. C++には名前空間がある。Dにはモジュールがある。この2つには明白な対応関係はない。
  6. C++では、ソースコードは(プリプロセスの後)1つの巨大なファイルとして扱われる。Dでは、 ソースコードはモジュールとパッケージの階層として扱われる。
  7. 列挙型の名前のスコープのルールは異なる。
  8. C++コードは、マクロ機能を組み込み機能に置き換える試みが数十年にわたって行われてきたにもかかわらず、 これまで以上に多くの任意マクロの層に依存している。 Dでは、トークン貼り付けや文字列化に相当する機能が常に存在するとは限らない。
  9. マクロ名は、#includeファイル全体にグローバルスコープを持つが、 巨大なソースファイル内ではローカルである。
  10. C++には任意の多重継承と仮想基底クラスがある。Dにはない。
  11. C++では、in、out、ref(すなわちinout)パラメータを区別しない。
  12. C++の名前の変更はコンパイラによって異なる。
  13. C++は、Objectの派生型だけでなく、任意の型の例外をスローする。
  14. C++のオーバーロードは、constとvolatileに基づいて行われる。Dのオーバーロードは constとimmutableに基づいて行われる。
  15. C++の演算子オーバーロードは、大幅に異なる方法で行われる。例えば、operator[]() のl値とr値に対するオーバーロードは、 constオーバーロードとプロキシクラスに基づいている。
  16. C++の演算子オーバーロードは、例えば < と > のように完全に独立している。
  17. C++では、クラスと構造体のオブジェクトを区別しない。
  18. vtbl[]の位置とレイアウトは、C++とDでは異なる。
  19. RTTIの方法は完全に異なる。C++にはクラス情報がない。
  20. Dには2段階検索もKoenig(ADL)検索も存在しない。
  21. C++ではクラスを「フレンド」システムに関連付けるが、Dではパッケージとモジュールを使用する。
  22. C++のクラス設計は明示的なメモリ割り当ての問題に重点を置く傾向があるが、 Dではそうではない。
  23. Dのテンプレートシステムは非常に異なる。
  24. C++には「例外仕様」がある。
  25. C++にはグローバルな演算子オーバーロードがある。
  26. C++の名前のマングリングは、constとvolatileが型修飾子であることに依存している。 Dの名前のマングリングは、constとimmutableが型修飾子であることに依存している。 Dのconstは、C++とは異なり、推移的でもある。Dでは、 constポインタを変更可能にすることはできない。

要するに、言語機能がコードの設計に影響を与えるということだ。C++の 設計はDには適合しない。たとえ自動的に適合させる方法を見つけられたとしても、 その成果は、ホンダをカマロの右側に溶接したようなもので、魅力的とは言えないだろう。


なぜDはガベージコレクションに参照カウント方式を採用しないのか?

参照カウントには利点もあるが、深刻な 欠点もある:

循環データ構造が解放されない。

提案されているC++のshared_ptr&lt;&gt;は、参照カウントを実装しているが、 これらの欠点のすべてに悩まされている。shared_ptr&lt;&gt;とマーク/スイープ方式のベンチマークを比較したものは見たことがないが、 shared_ptr&lt;&gt;がパフォーマンスとメモリ消費の両面で大きな敗者であることが判明しても、私は驚かないだろう。

とはいえ、Dは将来的にオプションとして何らかのリファレンスカウンティングをサポートする可能性がある。 rcはファイルハンドルのような希少なリソースの管理に適しているからだ。 さらに、リファレンスカウンティングが必須である場合、Phobosには std.typecons.RefCounted型 があり、C++のshared_ptrと同様に、ライブラリとして実装されている。


ガベージコレクションは遅くて非決定的ではないか?

はい、しかし、動的メモリ管理はすべて遅く、 非決定論的です。malloc/freeも同様です。 実際にリアルタイムソフトウェアを開発している人たちに話を聞くと、彼らはmalloc/freeを使用していない でしょう。

はい、しかし、動的メモリ管理はすべて遅く、 非決定論的です。malloc/free もその例外ではありません。 実際にリアルタイム・ソフトウェアを開発している人々に話を聞くと、 彼らは malloc/free を使用しない。なぜなら、それらは非決定論的だからだ。 彼らはすべてのデータを事前に割り当てる。 しかし、malloc の代わりに GC を使用することで、高度な言語構造(特に、より強力な配列構文)が可能になり、 メモリ割り当ての必要数を大幅に削減できる。 これは、明示的な管理よりもGCの方が実際には高速であることを意味する。


十分に賢いコンパイラであれば、関数が純粋であることを自動的に判断できるのではないか?

。 コンパイラは、デリゲートおよび関数リテラルについては純度(および安全性、およびnothrow)を推論する。 通常の関数については、いくつかの理由により、これを実行しない。

コンパイラは、デリゲートおよび関数リテラルについて純度(および安全性、nothrow)を推論する。 通常の関数については、いくつかの理由により、これを実行しない。

  1. ほとんどの関数は他の関数を呼び出し、その関数がさらに他の関数を呼び出すが、 そのうちの1つがライブラリルーチンを呼び出し、そのソースはコンパイラには利用できない。 そのため、純粋ではないと仮定しなければならない。 純粋関数属性を使用すると、純粋な外部ライブラリ関数を 純粋としてマークすることができ、分析が十分に機能するようになる
  2. 仮想関数(および派生するデリゲートや関数ポインタ)は、コンパイラが認識できない形でユーザーによって拡張される場合があるため、 それらは"純粋でない"と想定しなければならない。
  3. プログラマーが特定の関数を純粋にしようとして、 コンパイラーがそれを検知できなかった場合、プログラマーはそれに気づかない可能性がある。 さらに悪いことに、プログラマーがそれに気づいたとしても、 コンパイラーがそれを不純であると考える理由を特定するのは 非常に難しいかもしれない。それはプログラミングのミスなのか、それともコンパイラーのバグなのか? "function関数

動作しないはずのcast(float) をなぜ許可するのか?

浮動小数点数の規則では、xml-ph-0000@deepl.internal を xml-ph-0001@deepl.internal に変換することは 有効な変換である。 これは、浮動小数点数の

浮動小数点数の規則では、cast(real)cast(float)cast(real) に変換することは 有効な変換である。 これは、浮動小数点数の規則が以下の原則を念頭に置いて書かれているためである。

浮動小数点の精度が上がるとアルゴリズムが破綻する場合は、そのアルゴリズムは無効である。 浮動小数点の精度は常に最小値であり、最大値ではない。

最大精度に正当に依存していたプログラムは:

  1. コンパイラ/ライブラリの検証テストスイート
  2. 精度をプログラムでテストしようとするもの
(1) はユーザープログラミングにとって価値のあるものではなく、精度をテストする代替手段もある 。

(1) はユーザープログラミングにとっての"値"ではなく、精度をテストする代替手段も存在する。

(2) Dには、それを処理する.propertiesがある。

(2) Dには、それを処理する.propertiesがある。

最大精度に依存するプログラムは再考と再設計が必要である。


なぜネストされた関数は前方参照できないのか?

関数内の宣言は、モジュールスコープでの宣言とは異なる。 関数内では、変数宣言の初期化子は順次実行されることが保証されている。 任意のネストされた関数への前方参照を許可すると、 ネストされた関数はそれより上に宣言された任意の変数を参照できるため、この保証が破られることになる。

int first() { return second(); }
int x = first();   // xはまだ宣言されていないyに依存する。
int y = x + 1;
int second() { return y; }
しかし、ネストされた関数の前方参照が必要になることもある(例えば、 相互に再帰的なネストされた関数など)。最も一般的な解決策は、ローカルのネストされた構造体を宣言することである。 その構造体のすべてのメンバ関数(および変数!)は、

しかし、ネストした関数の前方参照が必要になることもある(例えば、 相互に再帰的なネストした関数など)。最も一般的な解決策は、ローカルのネストした構造体を宣言することである。 その構造体のすべてのメンバ関数(および変数!)は 非順次的な意味論を持つため、相互に前方参照が可能となる。