2016-08-02 52 views
1

Ich bin an C und C++ gewöhnt, wo die meisten grundlegenden Typen nicht spezifizierte Größen haben. Ich habe immer gedacht, dass diese nicht spezifizierten Größen existierten, um Effizienz über verschiedene Architekturen hinweg bereitzustellen.Warum werden D's Integraltypen anstelle von unspezifiziert festgelegt?

Doch nach der Verwendung von Sprachen wie Rust und D,
Ich sehe, dass alle ihre grundlegenden/primitiven Typen meist behoben sind.

Warum hat D gewählt, dass Typen nicht spezifizierter Größen weggelassen werden?
Beeinträchtigt dies nicht die Effizienz auf allen Maschinen?
Oder sind die Effizienzbedenken viel zu klein, um die Sicherheit der festen Typen zu überwiegen?

Ich hatte gehofft, etwas Literatur zu dieser Entscheidung zu finden, wie es nach zwei Sprachen gemacht wurde, die keine festen Größen als grundlegende Typen haben. Hoffentlich ist dies nicht zu opnionsbasiert.

+1

Die umgekehrte Frage ist hier: http://StackOverflow.com/Questions/35517341/Why-Sizeof-Built-in-Types-Except-Char-is-Compiler-dependent-In-CC Ich mag das Zitat, dass "Es macht die Sprache tragbarer, aber in der Sprache geschriebene Programme wahrscheinlich weniger tragbar". – Thilo

+1

Java hat auch feste Größen für Typen. Es macht es einfacher, Code zu schreiben, ohne den Code so schnell wie möglich zu machen. –

+1

Sie können plattformspezifische Typen verwenden, wenn Sie wirklich wollen, zum Beispiel 'size_t' ist' uint' auf x86 und 'ulong' auf x86_64 und' real' bietet Ihnen die höchstmögliche Präzision in Ihrer Architektur. – greenify

Antwort

4

In den wenigen Fällen, in denen die Größe eines ganzzahligen Typs tatsächlich systemspezifisch sein muss, haben diese Typen keine feste Größe in D - z. size_t und ptrdiff_t (weil sie mit der Größe von Zeigern umgehen und wie viel Speicher adressiert werden kann). Sie sind vielmehr Aliase für den entsprechenden Typ mit fester Größe. In ähnlicher Weise existieren Aliase wie c_long und c_long_double für die Interaktion mit C-Code. Diese müssen variable Größen haben, basierend auf der Plattform, auf der sie sich befinden, während für Dinge wie int oder long D hätte gehen können, aber was andere, moderne Sprachen wie Java und C# tat und ging mit feste Größen.

Wahrscheinlich, feste Größen tatsächlich verbessern Portabilität. Wenn Sie Code schreiben, der speziell für eine 32-Bit-Ganzzahl und nicht für eine Ganzzahl unbekannter Größe arbeitet, erhalten Sie konsistentes Verhalten auf allen Plattformen. Dies ist besonders kritisch im Umgang mit Dingen wie bitweisen Operationen, aber es kann Probleme mit Code im Allgemeinen reduzieren. Sie werden nicht plötzlich Probleme mit dem Überlauf bekommen, nur weil Sie Ihr Programm auf einer neuen Plattform kompiliert haben, die eine kleinere Ganzzahl hatte. Sie müssen nicht über jede Zeile Ihres Programms gehen, um sicherzustellen, dass die Integer-Größen auf einer neuen Plattform ordnungsgemäß mit dem Code funktionieren. Mit einer festen Integer-Größe wissen Sie, dass alle Fehler, die sich auf Integer-Größen beziehen, wenn sich Plattformen ändern, nicht auftreten. Daher ist Ihr Code so portierbar, dass Code, der Ganzzahlen mit variabler Größe verwendet, dies nicht tut.

Und in D-Code verursacht size_t manchmal Probleme für Programmierer, gerade weil seine Größe plattformabhängig ist. Code, der auf einer 64-Bit-Plattform kompiliert, kompiliert nicht auf einer 32-Bit-Plattform, wenn er eine long an eine size_t zuweisen kann, und Code, der kompiliert auf einer 32-Bit-Plattform nicht auf einem 64-Bit kompiliert Plattform, wenn es Sachen wie Assign size_t zu einem int tut. C/C++ hat weniger von diesen Problemen, denn im Gegensatz zu D gibt es keinen Fehler, die Conversions zu verringern, aber die C/C++ - Route zu gehen und diese Fehler nicht zu machen, würde bedeuten, dass es schwieriger ist, Bugs im Zusammenhang mit Conversions zu finden . Wenn D im Allgemeinen plattformabhängige Größen verwendet, würde jeder Compiler, der auf verengte Conversions prüft, ein sehr hohes Fehlerrisiko auf einigen Plattformen, aber nicht auf anderen Plattformen aufweisen, und Sie würden Fehler in Bezug auf Änderungen von Ganzzahlen (z. B. Überlauf) riskieren. auf einigen Plattformen, aber nicht auf anderen. Wenn Sie die Ganzzahlgrößen konsistent machen, wird der Code plattformübergreifend konsistent.

In der Vergangenheit war es bei einer Reihe von Architekturen tatsächlich der Fall, dass die Verwendung der "Wortgröße" der Maschine effizienter war, aber mit den heutigen Architekturen ist die Situation weitaus komplizierter.x86_64-Maschinen arbeiten mit 32-Bit-Ganzzahlen sehr effizient, so dass es ziemlich fraglich ist, dass 64-Bit-Ganzzahlen im Allgemeinen effizienter sind, und die Tatsache, dass 32-Bit-Ganzzahlen weniger Speicher benötigen, macht es wahrscheinlicher, dass Variablen innerhalb der CPU-Cache-Zeilen (sowie einfach weniger Speicher, der kopiert werden muss), so dass sie effizienter als 64-Bit-Ganzzahlen sein können. Aber es hängt vom Code, der genauen CPU und der tatsächlichen Arbeitslast ab. Es ist mein Verständnis, dass moderne x86-CPUs im Prinzip x86 emulieren, aber wirklich viel komplizierter sind als das unter der Haube (zB haben sie viel mehr Register in der Realität, als der x86-Mikrocode spielen muss), und sie verrichten alle möglichen verrückten Sachen vor 20 oder 30 Jahren nicht getan, um zu optimieren, was läuft. Also, die Situation ist Weg komplizierter als es einmal war, und erwartet, um einen Leistungsschub speziell weil Ihre Ganzzahlgröße entspricht der Wortgröße für die Maschine ist eine große Vereinfachung. Profiling ist erforderlich, um herauszufinden, was für eine bestimmte Anwendung am besten funktioniert, und es ist oft das komplette Gegenteil von dem, was Sie erwarten. Es ist also nicht unbedingt ein Vorteil, Ihre Integer-Größe mit der Wortgröße der Maschine abzugleichen und Ihren Code fehleranfälliger zu machen.

Persönlich ist es in C++ seit Jahren üblich, nur int zu verwenden, wenn es um Ganzzahlen geht, von denen ich weiß, dass sie relativ klein sind und keine bitweisen Operationen auf ihnen ausgeführt werden. Ansonsten verwende ich Typen wie int32_t und int64_t, und ich verwende nie Typen wie long oder short, denn sobald Sie verschiedene Integer-Typen verwenden müssen, um eine bestimmte Integer-Größe zu erhalten, ist es weniger anfällig für die Verwendung von Ganzzahlen fester Größe als einen Typ zu verwenden, der in einem bestimmten Bereich liegt. Und es gibt viele andere Leute da draußen, die das Gleiche tun. Ohne das zu tun, wenn Sie ein 32-Bit-Programm nehmen und es auf 64-Bit portieren müssen, werden Sie wie verrückt betet, dass Sie nicht in alle Arten von seltsamen, schwer aufzuspüren Fehler, die durch die Änderung von Integer-Größen verursacht werden. Wenn Sie jedoch eine ganze Zahl fester Größe verwenden, haben Sie keine dieser Bedenken.

Bei der Verwendung von Integer-Typen mit variabler Größe werden nur Fehler angezeigt, die plattformspezifisch sind, und es ist oft fraglich, ob dadurch die Leistung verbessert wird. An diesem Punkt scheinen die Ganzzahlen mit variabler Größe ein C-Ismus zu sein, den die meisten Sprachen, die danach kamen, nicht angenommen haben. Von dem, was ich gesehen habe, haben die meisten entweder überwiegend feste Größe Integer-Typen, oder sie haben das Äquivalent zu BigInt und trennen sich von den Hardware-Ganzzahlen vollständig. Und da D eine Systemsprache ist, ging es mit Ganzzahlen fester Größe vor, anstatt den eingebauten Integer-Typ wie einen BigInt zu wirken.