Die Frage ist klar.
Ich frage mich, warum sie das sogar für praktisch hielten, da eindeutig negative Indices in den Containern, die mit ihnen verwendet werden würden, nicht verwendbar wären (siehe zum Beispiel QList
's Dokumente ).
Ich dachte, sie wollten das für eine verrückte Art der Indexierung zulassen, aber es scheint nicht unterstützt zu sein?
Es erzeugt auch eine Menge (korrekter) Compiler-Warnungen über Casting und Vergleich von signierten / unsignierten Typen (auf MSVC).
Es scheint aus irgendeinem Grund einfach nicht mit der STL kompatibel zu sein ...
Weil Sie in der Regel arithmetische Berechnungen für Indizes durchführen möchten, können Sie also provisorische Provisorien erstellen. Dies ist eindeutig schmerzhaft, wenn der zugrundeliegende Indizierungstyp unsigniert ist.
Der einzige geeignete Zeitpunkt für die Verwendung von Zahlen ohne Vorzeichen ist die Modulusarithmetik. Wenn Sie "unsgined" als eine Art Kontraktbezeichner verwenden, ist eine Zahl im Bereich [0 ...] einfach ungeschickt und zu grob, um nützlich zu sein.
Überlegen Sie: Welchen Typ sollte ich verwenden, um die Idee darzustellen, dass die Zahl eine positive ganze Zahl zwischen 1 und 10 sein sollte? Warum ist 0 ... 2 ^ x ein spezieller Bereich?
Obwohl ich der Argumentation von Chris zutiefst sympathisch bin, werde ich hier widersprechen (zumindest teilweise spiele ich den Advokaten des Teufels). Es ist nichts Falsches daran, vorzeichenlose Typen für Größen zu verwenden, und es kann unter bestimmten Umständen sogar nützlich sein.
Chris hat für signierte Größentypen die Begründung, dass sie natürlich als Array-Indizes verwendet werden, und Sie könnten arithmetisch für Array-Indizes arbeiten, und diese Arithmetik könnte temporäre Werte erzeugen, die negativ sind.
Das ist in Ordnung, und vorzeichenlose Arithmetik bringt hier kein Problem mit sich, solange Sie sicherstellen, dass Sie Ihre Werte beim Vergleichen korrekt interpretieren. Da das Überlaufverhalten von Ganzzahlen ohne Vorzeichen vollständig angegeben ist, führen vorübergehende Überläufe in den negativen Bereich (oder in große positive Zahlen) zu keinem Fehler, solange sie korrigiert werden, bevor ein Vergleich durchgeführt wird.
Manchmal ist das Überlaufverhalten sogar wünschenswert, da das Überlaufverhalten der vorzeichenlosen Arithmetik bestimmte Bereichsüberprüfungen als einen einzigen Vergleich ausdrückbar macht, der andernfalls zwei Vergleiche erfordern würde. Wenn ich überprüfen möchte, ob x
im Bereich [a,b]
liegt und alle Werte vorzeichenlos sind, kann ich einfach Folgendes tun:
Das funktioniert nicht mit signierten Variablen; Solche Bereichsprüfungen sind bei Größen und Array-Offsets ziemlich üblich.
Ich erwähnte zuvor, dass ein Vorteil ist, dass Überlaufarithmetik Ergebnisse definiert hat. Wenn Ihre Indexarithmetik einen signierten Typ überschreitet, ist das Verhalten Implementierung definiert. Es gibt keine Möglichkeit, Ihr Programm portierbar zu machen. Verwenden Sie einen unsigned Typ und dieses Problem verschwindet. Zugegeben, dies gilt nur für große Offsets, aber es ist ein Anliegen für einige Anwendungen.
Grundsätzlich werden die Einwände gegen unsignierte Typen häufig überbewertet. Das eigentliche Problem ist, dass die meisten Programmierer nicht wirklich über die exakte Semantik des von ihnen geschriebenen Codes nachdenken, und für kleine Integer-Werte verhalten sich signierte Typen mehr im Einklang mit ihrer Intuition. Datengrößen wachsen jedoch ziemlich schnell. Wenn wir mit Puffern oder Datenbanken umgehen, liegen wir häufig weit außerhalb des Bereichs von "klein", und ein überzeichneter Überlauf ist weitaus problematischer als ein vorzeichenloser Überlauf. Die Lösung ist nicht "verwende keine unsignierten Typen", sondern "denke sorgfältig über den Code nach, den du schreibst und vergewissere dich, dass du es verstehst".