C ++: Gibt es einen Grund, uint64_t statt size_t zu verwenden?

7

Mein Verständnis von size_t ist, dass es groß genug sein wird, um irgendeinen (ganzzahligen) Wert zu halten, von dem Sie erwarten, dass er gehalten wird. (Vielleicht ist das eine schlechte Erklärung?)

Wenn Sie beispielsweise so etwas wie eine for-Schleife verwenden, um über alle Elemente in einem Vektor zu iterieren, wäre size_t typischerweise 64 Bit lang (oder zumindest auf meinem System), damit es alle möglichen Returns enthalten kann Werte von vector.size ().

Oder zumindest, ich denke, das ist richtig?

Gibt es deshalb einen Grund, A statt B zu verwenden?

A: for(uint64_t i = 0; i < v.size(); ++ i)

B: for(size_t i = 0; i < v.size(); ++ i)

Wenn ich mit meiner Erklärung falsch liege oder Sie eine bessere Erklärung haben, können Sie sie gerne bearbeiten.

Bearbeiten: Ich sollte hinzufügen, dass mein Verständnis ist, dass size_t verhält sich wie eine normale vorzeichenlose ganze Zahl - vielleicht ist das nicht korrekt?

    
user3728501 23.02.2015, 23:34
quelle

5 Antworten

8

size_t ist der Rückgabetyp von sizeof .

Der Standard sagt, es ist ein Typedef von einem vorzeichenlosen Integer-Typ und groß genug, um die Größe eines möglichen Objekts zu halten.
Es wird jedoch nicht festgelegt, ob es kleiner, größer oder gleich groß wie uint64_t ist (ein Typdef für eine 64-Bit-Ganzzahl ohne Vorzeichen mit fester Breite), und im letzteren Fall ist es nicht derselbe Typ.

Daher verwenden size_t semantisch korrekt.
Wie für size() von std::vector<T> ( std::vector erhält size_type vom verwendeten Zuordner, std::allocator<T> mit size_t ).

    
Deduplicator 23.02.2015 23:41
quelle
5

uint64_t ist garantiert für 64 Bit. Wenn Sie 64 Bits benötigen, sollten Sie es verwenden

size_t ist nicht garantiert für 64 Bits, könnte 128 Bits in einer zukünftigen Maschine sein. Also, Stichwort uint_64 ist davon reserviert:)

    
amchacon 23.02.2015 23:43
quelle
3

Der korrekte Fall wäre for(std::vector::size_type i ... .

Für den Zweck der Iteration durch einen Vektor oder etwas dieser Art wäre es schwierig, einen Fall zu finden, in dem size_t nicht groß genug ist und uint64_t ist,

Natürlich wäre size_t auf einer 32-Bit-Maschine normalerweise 32 Bit, aber Sie möchten vielleicht mit Zahlen umgehen, die größer als 4 Milliarden sind, was mehr als 32 Bit erfordern würde. Fall für uint64_t . Mit anderen Worten, uint64_t ist garantiert 64-Bit, size_t ist nicht 64 Bits in allen Maschinen / Architekturen.

    
Mats Petersson 23.02.2015 23:40
quelle
2

std::size_t ist als vorzeichenloser Integertyp definiert. Seine Länge hängt von der Plattform ab. v.size() gibt immer einen Wert vom Typ std::size_t zurück, daher ist Option B immer korrekt.

    
tmlen 23.02.2015 23:44
quelle
2

Nein, size_t hat absolut keine Verbindung zu "hält irgendeinen Integer-Wert, von dem Sie erwarten, dass er gehalten werden muss". Woher hast du das?

size_t soll groß genug sein, um die Byte-Größe jedes kontinuierlichen Objekts in der gegebenen Implementierung zu halten. Vom Konzept her ist dies weit weniger als "irgendein ganzzahliger Wert". Die Sprache garantiert nicht, dass Sie Objekte erstellen dürfen, die den gesamten adressierbaren Speicher belegen, was bedeutet, dass size_t konzeptionell nicht einmal ausreicht, die Anzahl der adressierbaren Speicherbytes zu halten.

Wenn Sie "irgendeinen ganzzahligen Wert" an die Speichergröße binden wollten, wäre der entsprechende Typ uintptr_t , was konzeptionell größer ist als size_t . Aber ich sehe keinen Grund, irgendeinen ganzzahligen Wert an die Speichereigenschaften zu binden. Z.B. Obwohl uintptr_t größer als size_t ist, ist es nicht garantiert, dass es groß genug ist, um die Größe der größten Datei im Dateisystem Ihrer Plattform zu speichern.

Der Grund, warum Sie size_t verwenden können, um über die Elemente von std::vector zu iterieren, ist, dass der Vektor intern auf einem Array basiert. Arrays sind kontinuierliche Objekte, weshalb ihre Größen von size_t abgedeckt sind. Wenn Sie jedoch einen nicht zusammenhängenden Container wie std::list , size_t berücksichtigen, reicht dies nicht mehr aus, um solche Container zu messen oder zu indizieren.

uint64_t kann einfacher größer sein als size_t . Es ist aber durchaus möglich, dass Sie mit Integer-Werten arbeiten müssen, die nicht in uint64_t passen.

    
AnT 23.02.2015 23:44
quelle

Tags und Links