Ist man mit der Programmiersprache D 2.0 anstatt C++ (C++11) schneller am Ziel?



  • volkard schrieb:

    Mal ein Beispiel schrieb:

    Okay, vergleichen wir mal:

    /* fussschuss.cpp */
    
    #include <iostream>
    
    using namespace std;
    
    int main(){
      bool kaputt = false;
    
      if (!kaputt){
        cout << "okay\n";
      }
      
      // aber C++ erlaubt es auch, mit schlechtem Stil sich in den Fuss zu schiesen:
      if (kaputt == false){
            cout << "okay\n";
      }
      // soweit noch okay, aber:
      if (kaputt = false){
            cout << "okay\n";
      } else {
        cout << "BUMMM!!!\n";
      }
      
      return 0;
    }
    

    Dazu zum Vergleich:

    /* Ich benutze mal das C Tag, weil es im Forum noch kein Tag für D gibt. */

    /* nix_fussschuss.d */
     
    import std.stdio;
     
    void main()
    {
      bool kaputt = false;
      
      if (!kaputt){
         writeln("okay\n");
      }
      
      // so weit okay, aber 
      if (kaputt == false){  // BUMM, Compilererror + Warnung, da nicht erlaubt
             writeln("okay\n");
      }
    
      // Wegen BUMM von oben kann das erst gar nicht passieren:
      if (kaputt = false){ // gibt alleine ebenfalls nen Compilererror
             writeln("okay\n");
      } else {
         writeln("BUMM!!!\n");
      }
      
      return 0;
    }
    

    Fazit:

    D vermeidet schlechten Stil, man läuft dadurch weniger Gefahr sich in den Fuss zu schiessen und ist somit schneller mit der Arbeit fertig.

    Compiler-Warnungen einschalten.

    Was die Sprache nicht kann, dass muss der Compiler fixen.
    So nach dem Motto?

    Und wer schreibt so miesen Code und macht ne Zuweisung in einer If Bedingung um dann anhand deren Wahrheitswert fortzufahren?
    Das ist IMO ganz schlechter Programmierstil.



  • Wenn C++ die Entwicklung nicht verlangsamt, wieso verwenden dann alle kleinen Indie Game Entwickler überwiegend Sprachen wie Java oder C#?

    Nur um mal ein paar sehr bekannte Beispiele zu nennen:

    Minecraft* -> Java
    Terraria -> C#
    Kerbal Space Program -> C#
    Project Zomboid -> Java

    * Okay, wurde schon genannt, aber der Vollständigkeit halber und weil es das bedeutendste Indie Spiel der letzten Jahre ist.)

    Bzw. warum wurden gerade die Indie Spiele, die am meisten her machen, also viel Aufwand vermuten lassen, in Java oder C# entwickelt?
    Meine Vermutung, die Projekte vergleichbarer Komplexität, die es in C++ versuchten, sind noch nicht fertig oder dauerten zu lange, so dass sie die Lust verloren haben.



  • Einspruch schrieb:

    Wenn C++ die Entwicklung nicht verlangsamt, wieso verwenden dann alle kleinen Indie Game Entwickler überwiegend Sprachen wie Java oder C#?

    Die Prämisse der ursprünglichen Frage hat nicht viel mit der Realität zu tun. Beispielsweise wurden Aspekte wie Vielfältigkeit der Standardbibliothek oder Güte des Tool-Supports ignoriert. Dem Fragesteller ging es anscheinend um das Potential einer Sprache, weniger um die tatsächlich aktuelle Entwicklungsgeschwindigkeit.

    Außerdem passen die Sprachen Java und C# hier meiner Meinung nach nicht so ganz in den Thread, weil sie nicht den Anspruch von C++ und D (bzgl "Systemprogrammierung") erheben wollen. Die Indie-Spieleentwickler nehmen wissentlich Performanceeinbußen in Kauf, wenn sie Java und C# verwenden -- wobei ich bei C# gegenüber Java noch den Vorteil sehe, dass man für leichtgewichtige struct s nicht extra den Heap bemühen muss und dadurch ein ggf besseres Speicherlayout erzielen kann. You get what you pay for.

    Und D scheint eher ein C# mit const / immutable und Templates zu sein. Ich muss zugeben, dass dieses "transitive const" für mich keinen Sinn ergibt. Kommt mir echt komisch vor. Kam mir auch komisch vor, als Alexandrescu für C++ mal im Usenet (comp.lang.c++ oder so) vorschlug, Konstruktoren mit const überladen zu können. Ich werde das Gefühl nicht los, als hätte er da bzgl const etwas nicht verstanden. Was mich auch davon abhält, mich mehr mit D zu beschäftigen, sind immer diese polemischen Passagen in Texten über D, die sich auf C++ beziehen und dabei aus Mücken Elefanten machen. Man merkt irgendwie, dass die D Entwickler Mühe haben, ihre Sprache zu verkaufen. Beispielsweise wird suggeriert, dass "transitives const" in C++ fehle, wobei es dort aber überhaupt keinen Sinn machen würde, weil Dir in C++ für Klassen auch keiner eine Indirektion aufzwingt ("reference types"). Du hast sozusagen schon "transitives const" bzgl echter Datenelemente, weil Du in C++ größere Objekte direkt aus kleineren zusammensetzen kannst. Aber das wird dann gerne mal unterschlagen.

    Ja, natürlich hat D nicht all die syntaktischen Krankheiten aus C++. Wäre ja auch blöd, wenn die D Entwlicker nicht aus C++ gelernt hätten. Aber sie haben versucht, den Spagat zwischen deterministisch aufgerufenen Destruktoren und nicht-deterministicher Garbage-Collection zu machen. Hatte aber nicht den Eindruck, als sei das gut gelungen. Es fühlte sich eher nach Feature-Creep an als ein durchdachtes Design.



  • kkaw schrieb:

    Aber sie haben versucht, den Spagat zwischen deterministisch aufgerufenen Destruktoren und nicht-deterministicher Garbage-Collection zu machen. Hatte aber nicht den Eindruck, als sei das gut gelungen. Es fühlte sich eher nach Feature-Creep an als ein durchdachtes Design.

    Hmm? Eine struct ist ein Objekt das auf dem Stack lebt und bei verlassen des Scopes zerstört wird, genau wie in C++. Eine Klasse ist polymorph, lebt auf dem Heap und wird zerstört wenn der GC sie einsammelt. Oder man ruft delete auf und zerstört sie sofort.

    Finde dass man damit eigentlich ziemlich genau die Werkzeuge hat um jeden Anwendungsfall elegant lösen zu können.



  • Im Grunde ist ja die Annahme dass ein Programm Müll erzeugt schon Müll.



  • Ethon schrieb:

    Hmm? Eine struct ist ein Objekt das auf dem Stack lebt und bei verlassen des Scopes zerstört wird, genau wie in C++. Eine Klasse ist polymorph, lebt auf dem Heap und wird zerstört wenn der GC sie einsammelt. Oder man ruft delete auf und zerstört sie sofort.

    Gibt's dann noch "RAII für Klassen" a la unique_ptr und co für deterministische Zerstörung? Darf man struct-Werte im Heap anlegen? Polymorphie ist ja eine Sache, Lebenszeit eine andere. Ich kann vielleicht doch nicht vorhersehen, ob ein Benutzer meinen struct-Typ direkt irgendwo einbetten will (Stack oder Datenmenber) oder eben doch im Heap halten will, um die Lebenszeit zu verlängern. Oder muss er dafür das Ding in ein 1-elementiges Array kopieren, was dann per Heap/GC gemanaged wird? Wie ernst nimmt D das "Ownership-Konzept"? Die Unterscheidung zwischen struct und class in D sowie C# wird als Vorteil verkauft. Ich sehe darin eine unnötige Inkonsistenz im Typsystem, welche generisches Programmieren erschweren könnte.



  • kkaw schrieb:

    Gibt's dann noch "RAII für Klassen" a la unique_ptr und co für deterministische Zerstörung?

    unique_ptr wäre mit minimalem Aufwand implementierbar wenn man ihn braucht. (Falls es soetwas nicht in der StdLib gibt, kA, nie gebraucht). Alternativ gibt es ScopeGuards mit denen man zb. folgendes machen könnte:

    void foo()
    {
        auto a1 = new A(), a2 = new A();
        scope(exit) destroy(a1); // a1 wird auf jeden Fall am Ende des Scopes zerstört.
        scope(failure) destroy(a2); // a2 wird nur zerstört wenn der Scope nicht fehlerfrei verlassen wird.
        mightThrow();
    }
    

    kkaw schrieb:

    Darf man struct-Werte im Heap anlegen? Polymorphie ist ja eine Sache, Lebenszeit eine andere. Ich kann vielleicht doch nicht vorhersehen, ob ein Benutzer meinen struct-Typ direkt irgendwo einbetten will (Stack oder Datenmenber) oder eben doch im Heap halten will, um die Lebenszeit zu verlängern. Oder muss er dafür das Ding in ein 1-elementiges Array kopieren, was dann per Heap/GC gemanaged wird? Wie ernst nimmt D das "Ownership-Konzept"?

    http://dlang.org/struct.html

    kkaw schrieb:

    Die Unterscheidung zwischen struct und class in D sowie C# wird als Vorteil verkauft. Ich sehe darin eine unnötige Inkonsistenz im Typsystem, welche generisches Programmieren erschweren könnte.

    Naja, D hat ein sehr ausgefeiltes Template/Trait System, generische Programmierung ist eigentlich kein Problem.



  • Ethon schrieb:

    Alternativ gibt es ScopeGuards

    Ih! Ja, ich erinnere mich... Noch cooler wär's natürlich, diese scope guards gar nicht hinschreiben zu müssen.

    Ethon schrieb:

    kkaw schrieb:

    Darf man struct-Werte im Heap anlegen? Polymorphie ist ja eine Sache, Lebenszeit eine andere. Ich kann vielleicht doch nicht vorhersehen, ob ein Benutzer meinen struct-Typ direkt irgendwo einbetten will (Stack oder Datenmenber) oder eben doch im Heap halten will, um die Lebenszeit zu verlängern. Oder muss er dafür das Ding in ein 1-elementiges Array kopieren, was dann per Heap/GC gemanaged wird? Wie ernst nimmt D das "Ownership-Konzept"?

    http://dlang.org/struct.html

    Auf der Seite war ich vorhin schon. Keine Ahnung, warum Du sie verlinkt hast. Sie scheint meine Fragen nicht zu beantworten. Oder ich habe es schon wieder übersehen. Ich kann da auch nicht drin erkennen, dass man sich per struct einen move-only Typen bauen kann, der eine Ressource besitzt. Müsstest Du mir als D-Profi mal zeigen, wie sowas geht. "postblit" kann das Original z.B. nicht anfassen. Von Move-Konstruktoren sehe ich da nichts. Und bei der Zuweisung werden auch nur Bits kopiert, was im Fall eines unique_ptr ein Speicherleck bedeuten würde. Zeig mir doch bitte, wie man in D folgendes nachbauen kann, ohne die Zahl von Heap-Allozierungen zu erhöhen:

    #include <iostream>
    #include <memory>
    
    unique_ptr<int> source() {
       return make_unique<int>(42);
    }
    
    void sink(unique_ptr<int> p) {
       std::cout << *p << std::endl;
    }
    
    int main() {
       sink(source());
    }
    

    Natürlich ist int hier nur ein Platzhalter für irgend eine andere Ressource, wo man keine sinnvolle Kopiersemantik für definieren kann. Ziel: Automatisches, aber deterministisches Freigeben der Resource. Ich will den GC doch nicht unnötig bemühen! ...besonders dann nicht, wenn er regelmäßig die Welt anhält.



  • kkaw schrieb:

    Ih! Ja, ich erinnere mich... Noch cooler wär's natürlich, diese scope guards gar nicht hinschreiben zu müssen.

    Deterministisch etwas zerstören zu müssen und es nicht dem GC zu überlassen sehe ich mal als Spezialfall an. Da kann man sich mal das etwas mehr tippen antun. Muss man in C++ ja immer.

    ---

    import std.typecons;
    import std.stdio;
    
    struct A
    {
        int v;
    
        this(int v)
        {
            this.v = v;
            writeln("Create");
        }
    
        this(this)
        {
            writeln("Postblit");
        }
    
        ~this()
        {
            writeln("Destroy");
        }
    }
    
    Unique!A source()
    {
       return Unique!A(new A(42));
    }
    
    void sink(Unique!A p)
    {
        writeln(p.v);
    }
    
    void main()
    {
        sink(source());
    }
    
    [ethon@desktop-fedora-20 WorkDir]$ ./bla 
    Create
    42
    Destroy
    

    Würde voll passen wenn die StdLib Implementierung von Unique nicht ewig brachliegen würde - vermutlich weil es nie jemand braucht - und der Typ nicht Kopien erlauben würde. 🙄
    Man kann sich aber einfach die Definition von Unique rauskopieren und das auskommentierte "this(this) = null;" durch "@disable this(this);" ersetzen.
    kA was bei denen los ist, wäre ich nicht so faul würde ich mal nachfragen was der Mist in der Stdlib soll.



  • Ethon schrieb:

    Hmm? Eine struct ist ein Objekt das auf dem Stack lebt und bei verlassen des Scopes zerstört wird, genau wie in C++.

    nur, daß eine struct in C++ kein *Objekt*, sondern eine *Klasse* ist, deren members und bases public sind, wenn nichts Anderes angegeben wird (im Unterschied zu class, wo sie privat sind, wenn nicht anders angegeben). Ein Objekt wird daraus durch Instanziierung.



  • Wir sind hier mit dem "wie funktioniert D" wahrscheinlich off-topic. Ist mir aber egal gerade ^^

    Ich frag' mich jetzt, was new A(42) in D zurückliefert, wenn es kein A ist, weil A ja kein Referenztyp ist. Aber es beantwortet schonmal meine Frage, ob sich so ein A überhaupt im Heap anlegen lässt. Zumindest sieht es für mich gerade wegen new so aus, als ob es im Heap landen würde. Das konnte ich leider bis jetzt der Online-Doku nicht entnehmen. Was für ein Heap wäre das? Ist das einer, den sich alle Threads teilen? Schenkt der GC der in Unique!A gespeicherten "Referenz" (oder "Zeiger", oder was auch immer die Terminologie in D dafür ist) irgend eine Aufmerksamkeit?

    Ich rate mal dass new T ein T* zurück gibt, falls T ein Werttyp ist, und sonst ein T . Sieht zumindest so aus, wenn ich bei der Implementierung von Unique reinschaue, die ich hier gefunden habe. Die "Doesn't work yet"-Kommentare irritieren mich da aber.

    Ethon schrieb:

    Deterministisch etwas zerstören zu müssen und es nicht dem GC zu überlassen sehe ich mal als Spezialfall an.

    Wenn der GC nicht deterministisch zerstört, kann man ihm die deterministische Zerstörung natürlich nicht überlassen. 🙂 Wie auch immer: Sehr schade, dass in D die Nutzung des GCs nicht als Ausnahme sondern als Regel verstanden wird. Wundert mich dann auch nicht, wenn man Teile (wie groß auch immer) der StdLib ohne GC nicht verwenden kann. Das beißt sich doch alles. Es kann doch nicht sein, dass man nicht-Speicher-Ressourcen nur per ScopeGuard managen können soll wenn man 'ne zeitige Freigabe haben möchte und nicht auf die Gunst des GCs angewiesen sein will, der irgendwelche Destruktoren irgengwann von irgendeinem Thread aus aufruft. Das skaliert doch nicht. Ich sehe nicht, wo mir D Mittel an die Hand gibt, Ownership und die damit verbundenen Pflichten von nicht-Speicher-Resourcen vernünftig zu delegieren. ScopeGuards sehen da wie eine Krücke aus. Sorry, aber ich habe lang genug Java programmiert und musste beim Wechsel zu C++ feststellen, dass C++ das Ressourcenproblem elegant und eben nicht nur für Speicherressourcen löst -- zumindest für all die Sachen, die ich so baue. Da will ich nicht wirklich zurück und mir irgendetwas andrehen lassen, was ich nicht brauche.

    Ethon schrieb:

    Würde voll passen wenn die StdLib Implementierung von Unique nicht ewig brachliegen würde

    Es passt also nicht? Was bedeutet das denn? Taugt Unique nichts? Was bedeuten die "doesn't work yet"-Kommentare da? Verstehe ich das richtig, dass D nicht wirklich zwischen Copy und Move unterscheiden kann? Ist Unique!A kopierbar und wenn ja, was passiert da bzgl double-delete?!

    Schönes WE und so!



  • großbuchstaben schrieb:

    Ethon schrieb:

    Hmm? Eine struct ist ein Objekt das auf dem Stack lebt und bei verlassen des Scopes zerstört wird, genau wie in C++.

    nur, daß eine struct in C++ kein *Objekt*, sondern eine *Klasse* ist, deren members und bases public sind, wenn nichts Anderes angegeben wird (im Unterschied zu class, wo sie privat sind, wenn nicht anders angegeben). Ein Objekt wird daraus durch Instanziierung.

    Also, man kann sich offenbar auch extra Mühr geben, jemanden falsch zu verstehen. Ist doch klar, was Ethon meinte -- auch wenn "Stack" natürlich dann nicht zutrifft, wenn es um Datenmember einer Klasse geht, die bei D ja dann immer im Heap leben würden. Springender Punkt: Weder in C++, C# noch in D hast du bei struct s eine aufgezwungene Indirektion. Immerhin. 🙂



  • kkaw schrieb:

    Weder in C++, C# noch in D hast du bei struct s eine aufgezwungene Indirektion. Immerhin. 🙂

    ...ist bei Rust übrigens auch so. 🙂 Aber von den genanngen Sprachen scheinen nur C++ und Rust die Sache mit "Ownership", "Moves" und deterministischer Freigabe richtig ernst zu nehmen.



  • Es ist doch völlig egal ob man mit D schneller ans Ziel kommt. Ist wie mit Windows , da gibt es die meiste Software für und die meisten Leute nutzen es.

    Daher ist es total egal, ob ein anderes System besser ist, wenn es nur wenige nutzen und es wenig dafür gibt geht es unter.



  • totalegal schrieb:

    Daher ist es total egal, ob ein anderes System besser ist, wenn es nur wenige nutzen und es wenig dafür gibt geht es unter.

    Man sollte ein Desktop Environment für Linux darin programmieren, dann würde die Sprache zum Selbstläufer werden, wenn das DE was taugt und Open Source ist.



  • kkaw schrieb:

    Ich frag' mich jetzt, was new A(42) in D zurückliefert, wenn es kein A ist, weil A ja kein Referenztyp ist. Aber es beantwortet schonmal meine Frage, ob sich so ein A überhaupt im Heap anlegen lässt. Zumindest sieht es für mich gerade wegen new so aus, als ob es im Heap landen würde. Das konnte ich leider bis jetzt der Online-Doku nicht entnehmen. Was für ein Heap wäre das? Ist das einer, den sich alle Threads teilen? Schenkt der GC der in Unique!A gespeicherten "Referenz" (oder "Zeiger", oder was auch immer die Terminologie in D dafür ist) irgend eine Aufmerksamkeit?

    Unique verwaltet nur einen Zeiger der dem GC ebenso bekannt ist.
    Wenn das Unique aus dem Scope geht dann wird delete aufgerufen, dh. das Objekt wird zerstört und der Speicher freigegeben.

    kkaw schrieb:

    Wenn der GC nicht deterministisch zerstört, kann man ihm die deterministische Zerstörung natürlich nicht überlassen. 🙂 Wie auch immer: Sehr schade, dass in D die Nutzung des GCs nicht als Ausnahme sondern als Regel verstanden wird. Wundert mich dann auch nicht, wenn man Teile (wie groß auch immer) der StdLib ohne GC nicht verwenden kann.

    Naja, ein GC erlaubt weit eleganteren, fehlerfreieren und oft performanteren Code. Macht imho schon Sinn diesen primär zu nutzen und nicht die ganze Zeit ein Auge auf Speicherverwaltung haben zu müssen.

    kkaw schrieb:

    Das beißt sich doch alles. Es kann doch nicht sein, dass man nicht-Speicher-Ressourcen nur per ScopeGuard managen können soll wenn man 'ne zeitige Freigabe haben möchte und nicht auf die Gunst des GCs angewiesen sein will, der irgendwelche Destruktoren irgengwann von irgendeinem Thread aus aufruft. Das skaliert doch nicht. Ich sehe nicht, wo mir D Mittel an die Hand gibt, Ownership und die damit verbundenen Pflichten von nicht-Speicher-Resourcen vernünftig zu delegieren. ScopeGuards sehen da wie eine Krücke aus. Sorry, aber ich habe lang genug Java programmiert und musste beim Wechsel zu C++ feststellen, dass C++ das Ressourcenproblem elegant und eben nicht nur für Speicherressourcen löst -- zumindest für all die Sachen, die ich so baue. Da will ich nicht wirklich zurück und mir irgendetwas andrehen lassen, was ich nicht brauche.

    Du kannst ja trotzdem mit structs arbeiten wenn du C++ vermisst, kommt ja dann auf das gleiche raus. struct die eine Resource wrappt.

    kkaw schrieb:

    Es passt also nicht? Was bedeutet das denn? Taugt Unique nichts? Was bedeuten die "doesn't work yet"-Kommentare da? Verstehe ich das richtig, dass D nicht wirklich zwischen Copy und Move unterscheiden kann? Ist Unique!A kopierbar und wenn ja, was passiert da bzgl double-delete?!

    Schönes WE und so!

    Unique - wie es aktuell in Phobos ist - ist Müll.
    Scheint aus einer sehr alten Zeit von D zu stammen als man noch nichtmal Kopien verbieten konnte, das ist nämlich auskommentiert.
    Muss da mal nen Patch einsenden.
    Mit dem kleinen Fix verhält es sich exakt wie MoveOnly-Typen in C++.



  • Ethon schrieb:

    Naja, ein GC erlaubt weit eleganteren, fehlerfreieren und oft performanteren Code. Macht imho schon Sinn diesen primär zu nutzen und nicht die ganze Zeit ein Auge auf Speicherverwaltung haben zu müssen.

    Wenn Du das so siehst, dann baust Du wohl ganz andere Anwendungen als ich. In meiner Anwendungsdomäne kann ich das, was Du da gesagt hast, nicht bestätigen. So gar nicht. Eine gewisse C++ Kompetenz unterstelle ich Dir da einfach mal. Aber offensichtlich fehlt Dir der Blick über den eigenen Tellerrand.

    Ethon schrieb:

    Du kannst ja trotzdem mit structs arbeiten wenn du C++ vermisst, kommt ja dann auf das gleiche raus. struct die eine Resource wrappt.

    Ich sehe nicht, wie Move-Semantik damit möglich sein soll. Hatte Dich ja auch gebeten, mir zu zeigen, wie man diese unique_ptr-Aufgabe in D schreiben würde. Aber da kam bisher nur der Hinweis auf ein verwaistes StdLib-Feature, dessen Quellcode mit "does not work yet" gespickt ist und was für mich im Moment so aussieht, als ob man ein Unique!A kopieren könnte, was zu einem double-delete führen würde. So funktioniert Move-Semantik nicht.

    Ethon schrieb:

    Unique - wie es aktuell in Phobos ist - ist Müll.

    Sieht so aus, ja.

    Ethon schrieb:

    Muss da mal nen Patch einsenden. Mit dem kleinen Fix verhält es sich exakt wie MoveOnly-Typen in C++.

    Dann zeig' doch mal endlich. Wie baut man in D structs (also ohne aufgezwungene Indirektion der "Referenztypen"), die nicht kopierbar aber movebar sind, wobei der struct-Autor festlegen kann, was bei einem Move passiert. Und wie skaliert das? Kann ich solche structs vernünftig schachteln oder muss das umschließende Struct sich um jeden Datenmember selbst kümmern, statt dass das die "Sub-Structs" erledigen? Nee, ich seh' nicht, dass das skaliert. Dafür sind structs in D einfach nicht gedacht ... was sehr schade ist ... aber auch diesen Java-lastigen Programmierstil bzgl Ressourcen in D erklärt. "optional GC" my ass.



  • IMO wer professional entwickelt/programmiert lässt die Hände weg. D ist ein inkonsistenter Paradigma-Mix mit verbuggter Entwicklungsplatform.



  • Zeus schrieb:

    D ist ein inkonsistenter Paradigma-Mix

    Beweise anhand von Beispielen!

    mit verbuggter Entwicklungsplatform.

    Nur weil eine Entwicklungsplattform noch unvollständig ist, ist sie nicht verbuggt.
    Außerdem, auf welche soll das zutreffen? Es gibt viele IDEs und es gibt bei D auch 3 Compiler.



  • Code bitte! schrieb:

    Zeus schrieb:

    D ist ein inkonsistenter Paradigma-Mix

    Beweise anhand von Beispielen!

    mit verbuggter Entwicklungsplatform.

    Nur weil eine Entwicklungsplattform noch unvollständig ist, ist sie nicht verbuggt.
    Außerdem, auf welche soll das zutreffen? Es gibt viele IDEs und es gibt bei D auch 3 Compiler.

    Beispiele sind keine Beweise, und weil ich schon IMO geschriebe ist die Forderung schon lächerlich. Abgesehen meine ich als Entwicklungsplatform, den Compiler, den Linker, die Laufzeitumgebung etc.


Anmelden zum Antworten