D ( dlangとも呼ばれる)は、Digital MarsのWalter Brightによって開発され、2001年にリリースされたマルチパラダイムシステムプログラミング言語です。Andrei Alexandrescuは2007年に設計と開発に加わりました。Dは当初C++のリエンジニアリングとして始まりましたが、現在では全く異なる言語となっています。開発が進むにつれて、他の高水準プログラミング言語からインスピレーションを得てきました。特に、 Java、Python、Ruby、C#、Eiffelの影響を受けています。
D言語のリファレンスでは、次のように説明されています。
D は、C に似た構文を持つ汎用システムプログラミング言語で、ネイティブコードにコンパイルされます。静的型付けで、自動 (ガベージコレクション) および手動メモリ管理の両方をサポートしています。D プログラムはモジュールとして構成され、個別にコンパイルして外部ライブラリとリンクすることで、ネイティブライブラリまたは実行可能ファイルを作成できます。[ 11 ]
D言語は一般的にC言語やC++言語のソースコードと互換性がありません。しかし、C/C++とD言語の両方で有効なコードは、同じように動作するはずです。
C++と同様に、D言語にはクロージャ、匿名関数、コンパイル時関数実行、契約による設計、範囲、組み込みのコンテナ反復概念、型推論といった機能があります。また、D言語の宣言、ステートメント、式の構文もC++のものとよく似ています。
C++とは異なり、D言語はガベージコレクション、第一級配列(std::arrayC++では厳密には第一級ではない)、配列スライス、ネストされた関数、遅延評価を実装しています。D言語は、C++スタイルの多重継承ではなく、インターフェースとミックスインを用いたJavaスタイルの単一継承を採用しています。
Dはシステムプログラミング言語です。C++と同様に、JavaやC#などのアプリケーション言語とは異なり、Dはインラインアセンブラを含む低レベルプログラミングをサポートしています。インラインアセンブラを使用すると、プログラマは標準のDコード内にマシン固有のアセンブリコードを入力できます。システムプログラマは、この方法を使用して、オペレーティングシステムやデバイスドライバなど、基盤となるハードウェアと直接インターフェースするプログラムを実行するために必要なプロセッサの低レベル機能にアクセスします。低レベルプログラミングは、コンパイラが生成するコードよりも高性能なコードを記述するためにも使用されます。
D言語は関数オーバーロードと演算子オーバーロードをサポートしています。シンボル(関数、変数、クラス)は任意の順序で宣言でき、前方宣言は不要です。
D言語では、テキスト文字列は文字の配列であり、D言語の配列は境界チェックされます。[ 12 ] D言語には複素数と虚数のための第一級型があります。 [ 13 ]
D言語は、主に5つのプログラミングパラダイムをサポートしています。
D言語における命令型プログラミングは、C言語における命令型プログラミングとほぼ同じです。関数、データ、ステートメント、宣言、式はC言語と同様に機能し、C言語のランタイムライブラリに直接アクセスできます。ただし、C言語とは異なり、D言語のforeachループ構造ではコレクションをループ処理できます。また、D言語ではネストされた関数も使用できます。ネストされた関数とは、別の関数内で宣言された関数であり、囲んでいる関数のローカル変数にアクセスできます。
import std.stdio ;void main () { int multiplier = 10 ; int scaled ( int x ) { return x * multiplier ; }foreach ( i ; 0 .. 10 ) { writefln ( "Hello, world %d! scaled = %d" , i , scaled ( i )); } }D言語におけるオブジェクト指向プログラミングは、単一の継承階層に基づいており、すべてのクラスはObjectクラスから派生します。D言語は多重継承をサポートしていません。代わりに、C++の純粋抽象クラスに相当するJavaスタイルのインターフェースと、共通の機能を継承階層から分離するミックスインを使用します。また、D言語では、インターフェース内で静的メソッドとfinal(非仮想)メソッドを定義することもできます。
D言語のインターフェースと継承は、オーバーライドされたメソッドの戻り値の型に対して共変型をサポートしています。
Dは型転送とオプションのカスタム動的ディスパッチをサポートしています。
D言語のクラス(およびインターフェース)には、契約による設計手法に従って、パブリックメソッドへのアクセス前後に自動的にチェックされる不変条件を含めることができます。
クラス(および構造体)の多くの側面は、コンパイル時(リフレクションを使用したリフレクティブプログラミングの一形態)および実行時(RTTI / )に自動的に内省することができ、汎用コードや自動コード生成(通常はコンパイル時技術を使用)を容易にします。type traitsTypeInfo
D は、関数リテラル、クロージャ、再帰的に不変なオブジェクト、高階関数の使用など、関数型プログラミング機能をサポートしています。匿名関数には、複数のステートメント形式と「省略形」の単一式表記の 2 つの構文があります。[ 14 ]
int function ( int ) g ; g = ( x ) { return x * x ; }; // 長い記述g = ( x ) => x * x ; // 短い記述function関数リテラルには、スタックに割り当てられた関数へのポインタである と、関連するスタック フレームdelegate、つまり現在のローカル変数を含む周囲の「環境」へのポインタも含む という2 つの組み込み型があります。匿名関数では型推論を使用できます。この場合、コンパイラは環境ポインタが不要であることを証明できない限り を作成します。同様に、クロージャを実装する場合、コンパイラは必要な場合にのみ(たとえば、クロージャが別の関数から返され、その関数のスコープから抜ける場合など)、囲まれたローカル変数をヒープに配置します。型推論を使用する場合、コンパイラは、適用可能であることを証明できれば、やなどの属性を関数の型に追加します。delegatepurenothrow
カリー化や、 map、filter、reduceなどの一般的な高階関数といったその他の機能は、標準ライブラリモジュールを通じて利用できますstd.functional。std.algorithm
import std.stdio , std.algorithm , std.range ;void main () { int [] a1 = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]; int [] a2 = [ 6 , 7 , 8 , 9 ];// 純粋関数内からアクセスできるようにするには、不変である必要がありますimmutable pivot = 5 ;int mySum ( int a , int b ) pure nothrow /* 純粋関数 */ { // 囲んでいるスコープへの参照if ( b <= pivot ) { return a + b ; } else { return a ; } }// デリゲート(クロージャ)を渡すauto result = reduce ! mySum ( chain ( a1 , a2 )); writeln ( "結果: " , result ); // 結果: 15// デリゲートリテラルを渡すresult = reduce !(( a , b ) => ( b <= pivot ) ? a + b : a )( chain ( a1 , a2 )); writeln ( "結果: " , result ); // 結果: 15 }あるいは、上記の関数合成は、より自然な左から右への読みやすさを実現するために、統一関数呼び出し構文(UFCS)を使用して表現することもできます。
auto result = a1.chain ( a2 ) .reduce ! mySum ( ); writeln ( "結果: " , result ) ;result = a1.chain ( a2 ) .reduce !(( a , b ) => ( b <= pivot ) ? a + b : a ) ( ) ; writeln ( "結果: " , result );並列プログラミングの概念はライブラリに実装されており、コンパイラによる追加のサポートは不要です。ただし、D型システムとコンパイラにより、データ共有が透過的に検出および管理されることが保証されます。
import std.stdio : writeln ; import std.range : iota ; import std.parallelism : parallel ;void main () { foreach ( i ; iota ( 11 ) .parallel ) { // foreachループの本体は各iに対して並列に実行されますwriteln ( "処理中" , i ); } }iota(11).parallelUFCSを使用することと同等ですstd.parallelism.parallel(iota(11))。
同じモジュールは、taskPool並列タスクの動的な作成や、範囲(および配列)に対するマップ・フィルタ・リデュースおよびフォールドスタイルの操作に使用できる機能もサポートしており、関数型操作と組み合わせると便利です。 は、std.algorithm.map配列ではなく遅延評価された範囲を返します。この方法では、各ワーカー タスクによって要素が自動的に並列に計算されます。
import std.stdio : writeln ; import std.algorithm : map ; import std.range : iota ; import std.parallelism : taskPool ;/* Intel i7-3930X および gdc 9.3.0 の場合: * std.algorithm.reduce を使用した場合 5140ms * std.parallelism.taskPool.reduce を使用した場合 888ms * * AMD Threadripper 2950X および gdc 9.3.0 の場合: * std.algorithm.reduce を使用した場合2864ms * std.parallelism.taskPool.reduce を使用した場合 95ms */ void main () { auto nums = iota ( 1.0 , 1_000_000_000.0 );auto x = taskPool.reduce ! " a + b" ( 0.0 , map ! "1.0 / (a * a)" ( nums ) );writeln ( "合計: " , x ); }並行処理はライブラリ内で完全に実装されており、コンパイラのサポートは不要です。並行コードの記述には、代替的な実装方法や手法も可能です。D型システムの使用は、メモリ安全性の確保に役立ちます。
import std.stdio , std.concurrency , std.variant ;void foo () { bool cont = true ;while ( cont ) { // デリゲートはメッセージタイプを照合するために使用されます。receive ( ( int msg ) => writeln ( "int received: " , msg ), ( Tid sender ) { cont = false ; sender.send ( -1 ); }, ( Variant v ) = > writeln ( "huh?" ) // Variant は任意のタイプに一致します) ; } }void main () { auto tid = spawn (& foo ); // foo() を実行する新しいスレッドを生成しますforeach ( i ; 0 .. 10 ) { tid . send ( i ); // いくつかの整数を送信}tid.send ( 1.0f ); // float を送信tid.send ( " hello " ); // string を送信tid.send ( thisTid ) ; // struct(Tid )を送信receive (( int x ) => writeln ( "メインスレッドがメッセージを受信しました: " , x )); }メタプログラミングは、テンプレート、コンパイル時関数実行、タプル、および文字列ミックスインによってサポートされています。以下の例は、D言語のコンパイル時機能の一部を示しています。
D言語のテンプレートは、C++の関数型テンプレートに比べて、より命令的なスタイルで記述できます。以下は、数値の階乗を計算する通常の関数です。
ulong階乗( ulong n ) { if ( n < 2 ) { 1を返す; } else { return n *階乗( n - 1 ); } }ここでは、D言語のコンパイル時条件構文である`<`を使用してstatic if、上記の関数と同様のコードで同じ計算を実行するテンプレートを構築する方法を示します。
template Factorial ( ulong n ) { static if ( n < 2 ) { enum Factorial = 1 ; } else { enum Factorial = n * Factorial !( n - 1 ); } }以下の2つの例では、上記で定義したテンプレートと関数を使用して階乗を計算します。定数の型は明示的に指定する必要はありません。コンパイラが代入式の右辺から型を推論します。
enum factorial7 = Factorial !( 7 );これはコンパイル時関数実行(CTFE)の一例です。通常の関数は、特定の条件を満たしていれば、定数コンパイル時式で使用できます。
enum factorial9 = factorial ( 9 );このstd.string.format関数はprintf、コンパイル時にCTFEを介して、データフォーマットと同様の処理を実行し、「msg」プラグマはコンパイル時に結果を表示します。
import std.string : format ;pragma ( msg , format ( "7! = %s" , fact_7 )); pragma ( msg , format ( "9! = %s" , fact_9 ));文字列ミックスインとコンパイル時関数実行を組み合わせることで、コンパイル時に文字列操作を用いたDコードを生成することが可能になります。これは、プログラムの一部としてコンパイルされるドメイン固有言語の解析に利用できます。
// Foo ソースコードを解析し、同等の D コードを返す関数を含む仮想モジュールimport FooToD ;void main () { mixin ( fooToD ( import ( "example.foo" ))); }メモリ管理は通常ガベージコレクションによって行われますが、特定のオブジェクトはスコープ外になった時点で即座にファイナライズされる場合があります。D言語で書かれたプログラムやライブラリの大部分はこの方式を採用しています。
明示的なメモリ管理は、オーバーロードされた演算子new を使用したり、Cのmalloc と free を直接呼び出したり、フォールバック付きスタック割り当て、RAII スタイルの割り当て、参照カウント、共有参照カウントなどのカスタム割り当て方式を実装したりすることで可能です。ガベージ コレクションは制御できます。プログラマは、コレクタが監視するメモリ範囲を追加および除外したり、コレクタを無効および有効にしたり、世代別または完全なコレクション サイクルを強制したりできます。[ 15 ]言語ドキュメントには、ガベージ コレクションが望ましくないシナリオで代替のメモリ管理方式を実装する方法の例が記載されています。[ 16 ]
関数では、structインスタンスはデフォルトでスタックに割り当てられますが、classインスタンスはデフォルトでヒープに割り当てられます(スタックにはクラスインスタンスへの参照のみが存在します)。ただし、クラスの場合は、たとえば標準ライブラリのテンプレートを使用したりstd.typecons.scoped、構造体にを使用したりnew、値ベースの変数ではなくポインタに代入したりすることで、これを変更できます。[ 17 ]
関数では、静的配列(サイズが既知のもの)はスタック上に割り当てられます。動的配列の場合は、core.stdc.stdlib.alloca関数(C言語の に類似alloca)を使用してスタック上にメモリを割り当てることができます。返されたポインタは、スライスを使用して(型付きの)動的配列に(再キャスト)することができます(ただし、配列のサイズ変更(追加を含む)は避ける必要があります。また、明らかな理由から、関数から返してはなりません)。[ 17 ]
キーワードscopeは、コードの一部だけでなく、変数やクラス/構造体にも注釈を付けるために使用でき、スコープを抜ける際にすぐに破棄(デストラクタ呼び出し)する必要があることを示します。メモリの解放方法は、実装やクラスと構造体の違いにも依存します。[ 18 ]
std.experimental.allocator特定のユースケースに合わせてカスタムアロケータを作成するための、モジュール式で構成可能なアロケータテンプレートが含まれています。[ 19 ]
SafeD [ 20 ]は、メモリが安全で あることが保証されている D のサブセットに付けられた名前です。 とマークされた関数は@safe、ポインタ演算やチェックされていないキャストなど、メモリの破損につながる可能性のある機能を使用していないことを確認するために、コンパイル時にチェックされます。 と呼び出される他の関数も、またはとしてマークする必要があります@safe。@trustedコンパイラ@trustedが SafeD で無効になっている機能の安全な使用とメモリ破損の可能性のあるケースを区別できない場合は、関数をマークできます。[ 21 ]
当初は DIP1000 [ 22 ]および DIP25 [ 23 ] (現在は言語仕様の一部[ 24 ]となっている) の旗印の下で、D はデータの寿命に関わる特定の不正な構造に対する保護を提供します。
現在導入されているメカニズムは主に関数パラメータとスタックメモリを扱っていますが、言語設計ロードマップには、Rustプログラミング言語の概念を取り入れてDプログラミング言語内でライフタイムトラッキングを拡張する計画が含まれています。[ 25 ] ( Rustプログラミング言語のアイデアに影響を受けている)。
@safeコード内では、参照型を含む代入の有効期間がチェックされ、代入先の有効期間が代入先の有効期間よりも長いことが保証されます。
例えば:
@safe void test () { int tmp = 0 ; // #1 int * rad ; // #2 rad = & tmp ; // #1 と #2 の宣言順序が逆の場合、これは失敗します。{ int bad = 45 ; // "bad" の有効期間は、それが定義されているスコープ内にのみ及びます。* rad = bad ; // これは有効です。rad = & bad ; // rad の有効期間は bad より長いため、これは無効です。} }ポインタ型または参照型の関数パラメータに適用した場合、キーワードreturnとscope はそのパラメータの有効期間と使用を制限します。
言語標準では、次の動作が規定されています。[ 26 ]
注釈付きの例を以下に示します。
@安全:int * gp ; void thorin ( scope int *); void gloin ( int *); int * balin ( return scope int * p , scope int * q , int * r ) { gp = p ; // エラー、p がグローバル変数 gp にエスケープします。gp = q ; // エラー、q がグローバル変数 gp にエスケープします。gp = r ; // OK。thorin ( p ); // OK、p は thorin() からエスケープされません。thorin ( q ); // OK。thorin ( r ); // OK。鼠径部( p ); // エラー。p は gloin() をエスケープします。鼠径部( q ); // エラー。q は gloin() をエスケープします。鼠径部( r ); // r は gloin() をエスケープします。return p ; // OK。return q ; // エラー、'scope' q を返すことはできません。return r ; // OK。}C言語のアプリケーションバイナリインターフェース(ABI)がサポートされており、C言語のすべての基本型と派生型もサポートされているため、既存のCコードやライブラリに直接アクセスできます。多くの一般的なCライブラリにはD言語のバインディングが用意されています。さらに、C言語の標準ライブラリは標準D言語の一部となっています。
Microsoft Windowsでは、D言語はコンポーネントオブジェクトモデル(COM)コードにアクセスできます。
メモリ管理が適切に行われる限り、D と他の多くの言語を単一のバイナリに混在させることができます。たとえば、GDC コンパイラでは、C、C++、および Objective-C などのサポートされている言語のコードをリンクして混在させることができます。D コード (関数) は、C、C++、Pascal ABI を使用するようにマークすることもでき、これらの言語で記述されたライブラリにコールバックとして渡すことができます。同様に、これらの言語で記述されたコード間でデータを双方向に交換することもできます。通常、これにより使用できるのはプリミティブ型、ポインタ、一部の配列形式、共用体、構造体、および一部の型の関数ポインタに限定されます。
他の多くのプログラミング言語は、拡張機能を作成したり、言語のインタプリタを実行したりするためのC アプリケーション プログラミング インターフェイス ( API ) を提供しているため、D は標準の C バインディング (薄い D インターフェイス ファイルを使用) を使用して、これらの言語と直接インターフェースすることもできます。たとえば、 Python [ 27 ] 、Lua [ 28 ] [ 29 ]などの言語には双方向バインディングが存在し、多くの場合、コンパイル時のコード生成とコンパイル時の型リフレクション メソッドを使用しています。
とマークされたDコードについては、以下の機能が指定されています。extern(C++)
C++ の名前空間は、次の構文で使用されます。
extern ( C ++ 、名前空間)namespaceC++名前空間の名前はどこですか。
C++の場合:
import std ;class Base { public : virtual void print3i ( int a , int b , int c ) = 0 ; };class Derived : public Base { private : int field ; public : explicit Derived ( int field ) : field ( field ) {}void print3i ( int a , int b , int c ) { std :: println ( "a = {}" , a ); std :: println ( "b = {}" , b ); std :: println ( "c = {}" , c ); }int mul ( int factor ) { return field * factor ; } };Derived * createInstance ( int i ) { return new Derived ( i ); }void deleteInstance ( Derived *& d ) { delete d ; d = 0 ; }Dについて:
extern ( C ++) { abstract class Base { public : void print3i ( int a , int b , int c ); }class Derived : Base { private : int field ; public : @disable this (); override void print3i ( int a , int b , int c ); final int mul ( int factor ); }Derived createInstance ( int i ); void deleteInstance ( ref Derived d ); }void main () { import std . stdio ;auto d1 = createInstance ( 5 ) ; writeln ( d1.field ) ; writeln ( d1.mul ( 4 ) ) ;Base b1 = d1 ; b1 . print3i ( 1 , 2 , 3 );deleteInstance ( d1 ); assert ( d1はnullです);auto d2 = createInstance ( 42 ) ; writeln ( d2.field ) ;deleteInstance ( d2 ); assert ( d2はnullです); }D プログラミング言語には、「 Better C 」として知られる公式のサブセットがあります。[ 30 ]このサブセットでは、C 以外のランタイムライブラリの使用を必要とする D 機能へのアクセスが禁止されています。
DMDおよびLDCではコンパイラフラグ「-betterC」、GDCでは「-fno-druntime」によって有効化されるBetter Cは、同じフラグでコンパイルされたDコード(およびD以外のリンクされたコード)のみを呼び出すことができますが、Better Cオプションなしでコンパイルされたコードは、このオプション付きでコンパイルされたコードを呼び出すことができます。ただし、CとDではアサートの処理方法が異なるため、動作が若干異なります。
scope(exit)assertエラーはCランタイムライブラリに転送されますswitch弦楽器付きfinal switchunittestブロックprintf()フォーマット検証core.thread)synchronizedそしてcore.syncウォルター・ブライトは1999年に新しい言語の開発に着手した。Dは2001年12月に初めてリリースされ[ 1 ]、2007年1月にバージョン1.0に達した[ 31 ]。言語の最初のバージョン(D1)は、C++と同様に、命令型、オブジェクト指向、メタプログラミングのパラダイムに重点を置いていた[ 32 ]。
D コミュニティの一部のメンバーは、D の公式ランタイムおよび標準ライブラリである Phobos の代替として Tango という代替ランタイムおよび標準ライブラリを作成しました。最初の Tango の公開発表は、D 1.0 のリリースから数日後に行われました。[ 33 ] Tango は、OOP と高いモジュール性を採用した、異なるプログラミング スタイルを採用しました。コミュニティ主導のプロジェクトであるため、Tango は貢献に対してよりオープンであり、公式標準ライブラリよりも速く進歩することができました。当時、Tango と Phobos は、ランタイム サポート API (ガベージ コレクタ、スレッド サポートなど) が異なるため互換性がありませんでした。そのため、同じプロジェクトで両方のライブラリを使用することは不可能でした。広く使用されているライブラリが 2 つ存在していたため、一部のパッケージは Phobos を使用し、他のパッケージは Tango を使用するようになり、さまざまなプロジェクト間で非互換性が生じました。[ 34 ]
2007 年 6 月に D2 の最初のバージョンがリリースされました。[ 35 ] D2 の開発開始は、D1 の安定化を意味しました。言語の最初のバージョンはメンテナンス状態に置かれ、修正と実装上のバグ修正のみが行われています。D2 は、最初のconst システムから始まる言語の破壊的変更を導入しました。D2 は後に、クロージャ、純粋性、関数型プログラミングと並行プログラミングのパラダイムのサポートなど、他の多くの言語機能を追加しました。D2はまた、ランタイムを標準ライブラリから分離することで、標準ライブラリの問題を解決しました。D2 Tango の移植完了は 2012 年 2 月に発表されました。[ 36 ]
2010年6月12日にアンドレイ・アレクサンドレスクの著書『Dプログラミング言語』が出版されたことで、D2は安定した状態となり、今日では一般的に単に「D」と呼ばれている。
2011年1月、D言語の開発はバグトラッカー/パッチ提出方式からGitHubに移行しました。これにより、コンパイラ、ランタイム、標準ライブラリへの貢献が大幅に増加しました。[ 37 ]
2011年12月、アンドレイ・アレクサンドレスクは、言語の最初のバージョンであるD1が2012年12月31日に廃止されることを発表した。[ 38 ] D1の最終リリースであるD v1.076は、2012年12月31日にリリースされた。[ 39 ]
公式の D コンパイラである Walter Bright によるDigital Mars D コンパイラのコードは、当初はカスタムライセンスの下でリリースされ、ソースは利用可能でしたが、オープンソース定義には準拠していませんでした。[ 40 ] 2014 年に、コンパイラのフロントエンドはBoost ソフトウェア ライセンスの下でオープンソースとして再ライセンスされました。[ 3 ]この再ライセンスされたコードには、 Symantecで部分的に開発されていたバックエンドは含まれていませんでした。2017 年 4 月 7 日、Symantec がバックエンドの再ライセンスも許可した後、コンパイラ全体が Boost ライセンスの下で利用可能になりました。[ 4 ] [ 41 ] [ 42 ] [ 43 ] 2017 年 6 月 21 日、D 言語が GCC に組み込まれることが承認されました。[ 44 ]
現在主流のD言語実装のほとんどは、機械語に直接コンパイルされる。
実運用対応コンパイラ:
おもちゃや概念実証用のコンパイラ:
上記のコンパイラとツールチェーンを使用すると、 IA-32、amd64、AArch64、PowerPC、MIPS64、DEC Alpha、Motorola m68k、SPARC、s390、WebAssemblyなど、さまざまなアーキテクチャをターゲットとするDプログラムをコンパイルできます。主なサポート対象オペレーティングシステムはWindowsとLinuxですが、さまざまなコンパイラは、ホストまたはターゲット、あるいはその両方として、Mac OS X 、 FreeBSD 、 NetBSD 、 AIX 、 Solaris /OpenSolaris、Androidもサポートしています。WebAssemblyターゲット(LDCとLLVMでサポート)は、最新のWebブラウザ( Google Chrome、Mozilla Firefox、Microsoft Edge、Apple Safari)や専用のWasm仮想マシンなど、あらゆるWebAssembly環境で動作できます。
この言語の構文ハイライトと部分的なコード補完をサポートするエディタや統合開発環境(IDE)には、 SlickEdit、Emacs、vim、SciTE、Smultron、Zeus [ 57 ]、Geany [ 58 ]などがあります。
Windows用のオープンソースD IDE が存在し、Poseidon [ 71 ] 、 D-IDE [ 72 ]、Entice Designer [ 73 ]など、D 言語で書かれたものもあります。
D アプリケーションは、 GNU デバッガー(GDB) やWinDbgなどの C/C++ デバッガーを使用してデバッグできますが、D 固有のさまざまな言語機能のサポートは非常に限られています。Windows では、cv2pdbを使用してデバッグ情報を変換した後、 Ddbgまたは Microsoft のデバッグ ツール (WinDBG および Visual Studio)を使用して D プログラムをデバッグできます。Linux用のZeroBUGSデバッガーは、 D 言語の実験的なサポートを備えています。Ddbg はさまざまな IDE またはコマンドラインから使用できます。ZeroBUGS には独自のグラフィカル ユーザー インターフェイス(GUI) があります。
DustMiteはDソースコードを最小化するためのツールで、コンパイラやテストの問題を見つける際に役立ちます。[ 74 ]
dubはDアプリケーションやライブラリ向けの人気のパッケージおよびビルドマネージャであり、IDEサポートに統合されていることが多い。[ 75 ]
D プログラミング言語をプロジェクトに使用している著名な組織には、Facebook [ 76 ] 、eBay [ 77 ]、Netflix [ 78 ]などがあります。
D は、AAAゲーム[ 79 ] 、インディー ゲーム[ 80 ]、言語インタプリタ、仮想マシン[ 81 ] [ 82 ] 、オペレーティングシステム カーネル[ 83 ]、GPUプログラミング[ 84 ]、Web 開発[ 85 ] [ 86 ] 、数値解析[ 87 ]、GUI アプリケーション[ 88 ] [ 89 ]、乗客情報システム[ 90 ] 、機械学習 [ 91 ]、テキスト処理、 Web およびアプリケーション サーバー、研究などに成功裏に使用されています。
北朝鮮のハッキンググループLazarusは、 CVE-2021-44228、別名「Log4Shell」を悪用して、DLangで書かれた3つのマルウェアファミリーを展開した。 [ 92 ]
開発プロセスの俊敏性の欠如とD言語への変更導入の難しさについては、元貢献者によるブログ記事[ 93 ]で説明されています。そこで述べられている明らかな不満が、2024年1月1日のOpenDフォーク[ 94 ]につながりました。
主要なコンピュータ雑誌では、D について言及されることはほとんどありません。2026 年 7 月現在、D はTIOBE インデックスで 41 位にランクされています。[ 95 ] D は 2016 年に 24 位でした。[ 96 ]これは、マーケティングが著しく不足しているためです。全体的な状況は、コンピュータ雑誌Wired が「聞いたことのない次の大きなプログラミング言語」という記事を掲載した 2014 年とほとんど変わっていません。[ 97 ]このため、馴染みやすさによるバイアスや安定性に関する不確実性が生じることがあります。[ 98 ]