unsigned int vs. size_t

Lesezeit: 6 Minuten

Ich stelle fest, dass moderner C- und C++-Code verwendet zu werden scheint size_t anstatt int/unsigned int so ziemlich überall – von Parametern für C-String-Funktionen bis zur STL. Ich bin gespannt auf den Grund dafür und die Vorteile, die es bringt.

unsigned int vs size t
Remo.D

Die size_t Typ ist der Ganzzahltyp ohne Vorzeichen, der das Ergebnis von ist sizeof Betreiber (und die offsetof Operator), so dass es garantiert groß genug ist, um die Größe des größten Objekts aufzunehmen, das Ihr System verarbeiten kann (z. B. ein statisches Array von 8 GB).

Die size_t Typ kann größer, gleich oder kleiner als ein sein unsigned intund Ihr Compiler kann zur Optimierung Annahmen darüber treffen.

Genauere Informationen finden Sie im C99-Standard, Abschnitt 7.17, von dem ein Entwurf im Internet verfügbar ist pdf -Format oder im C11-Standard, Abschnitt 7.19, auch verfügbar als pdf-Entwurf.

  • Nö. Denken Sie an x86-16 mit dem großen (nicht riesigen) Speichermodell: Zeiger sind weit (32 Bit), aber einzelne Objekte sind auf 64 KB begrenzt (so dass size_t 16 Bit sein kann).

    – dan04

    28. November 2010 um 3:46 Uhr

  • “Größe des größten Objekts” ist keine schlechte Formulierung, sondern absolut richtig. Die Sechs eines Objekts kann viel eingeschränkter sein als der Adressraum.

    – gnasher729

    12. April 2014 um 21:39 Uhr

  • “Ihr Compiler könnte davon ausgehen”: Ich würde hoffen, dass der Compiler weiß der genaue Wertebereich, dass size_t darstellen kann! Wenn nicht, wer tut es?

    – Marc van Leeuwen

    15. Juni 2014 um 5:42 Uhr

  • @Marc: Ich denke, der Punkt war eher, dass der Compiler dazu in der Lage sein könnte etwas tun mit diesem wissen.

    Benutzer1084944

    31. August 2015 um 22:02 Uhr


  • Ich wünschte nur, dass dieser immer beliebter werdende Typ keine Header-Datei erfordern würde.

    – Benutzer2023370

    11. November 2016 um 10:26 Uhr

1647070812 408 unsigned int vs size t
azeemarif

Klassisches C (der frühe Dialekt von C, der von Brian Kernighan und Dennis Ritchie in The C Programming Language, Prentice-Hall, 1978 beschrieben wurde) bot keine size_t. Der C-Normenausschuss eingeführt size_t um ein Portabilitätsproblem zu beseitigen

Ausführlich erklärt auf embedded.com (mit einem sehr guten Beispiel)

  • Ein weiterer großartiger Artikel, der sowohl size_t als auch ptrdiff_t erklärt: viva64.com/en/a/0050

    – Ihor Kaharlichenko

    15. Juni 2011 um 13:58 Uhr

unsigned int vs size t
Rose Perrone

Zusamenfassend, size_t ist nie negativ und maximiert die Leistung, weil es als Typ einer vorzeichenlosen Ganzzahl definiert ist, die groß genug – aber nicht zu groß – ist, um die Größe des größtmöglichen Objekts auf der Zielplattform darzustellen.

Größen sollten niemals negativ sein, und zwar size_t ist ein vorzeichenloser Typ. Auch weil size_t vorzeichenlos ist, können Sie Zahlen speichern, die ungefähr doppelt so groß sind wie im entsprechenden vorzeichenbehafteten Typ, da wir das Vorzeichenbit zur Darstellung der Größe verwenden können, wie alle anderen Bits in der vorzeichenlosen Ganzzahl. Wenn wir ein weiteres Bit gewinnen, multiplizieren wir den Zahlenbereich, den wir darstellen können, mit einem Faktor von etwa zwei.

Sie fragen sich also, warum nicht einfach ein verwenden unsigned int? Es ist möglicherweise nicht in der Lage, große Zahlen aufzunehmen. In einer Implementierung wo unsigned int 32 Bit ist, ist die größte Zahl, die es darstellen kann 4294967295. Einige Prozessoren, wie der IP16L32, können Objekte kopieren, die größer sind als 4294967295 Byte.

Sie fragen also, warum nicht ein verwenden unsigned long int? Auf einigen Plattformen fordert es einen Leistungszoll. Standard C verlangt, dass a long mindestens 32 Bit belegen. Eine IP16L32-Plattform implementiert jede 32-Bit-Länge als ein Paar von 16-Bit-Wörtern. Fast alle 32-Bit-Operatoren auf diesen Plattformen benötigen zwei Anweisungen, wenn nicht mehr, da sie mit den 32 Bits in zwei 16-Bit-Blöcken arbeiten. Zum Beispiel erfordert das Verschieben einer 32-Bit-Datei normalerweise zwei Maschinenanweisungen – eine, um jeden 16-Bit-Block zu verschieben.

Verwenden size_t vermeidet diesen Leistungszoll. Entsprechend dieser fantastische Artikel“Art size_t ist eine Typedef, die normalerweise ein Alias ​​für einen vorzeichenlosen Integer-Typ ist unsigned int oder unsigned longaber möglicherweise sogar unsigned long long. Jede Standard-C-Implementierung soll die vorzeichenlose Ganzzahl wählen, die groß genug ist – aber nicht größer als nötig – um die Größe des größtmöglichen Objekts auf der Zielplattform darzustellen.

  • Tut mir leid, das nach so langer Zeit kommentieren zu müssen, aber ich musste nur die größte Zahl bestätigen, die ein unsigned int halten kann – vielleicht verstehe ich Ihre Terminologie falsch, aber ich dachte, dass die größte Zahl, die ein unsigned int halten kann, 4294967295 ist, 65356 ist das Maximum eines vorzeichenlosen Kurzschlusses.

    – Mitsch

    9. April 2012 um 11:05 Uhr

  • Wenn Ihr unsigned int 32 Bits belegt, dann ja, die größte Zahl, die es aufnehmen kann, ist 2 ^ 32 – 1, was 4294967295 (0xffffffff) ist. Hast du noch eine Frage?

    – Rose Perrone

    11. April 2012 um 4:24 Uhr

  • @Mitch: Der größte Wert, der in einem dargestellt werden kann unsigned int kann und wird von einem System zum anderen variieren. Es muss sein wenigstens 65536aber es ist allgemein 4294967295 und sein könnte 18446744073709551615 (2**64-1) auf einigen Systemen.

    – Keith Thompson

    12. April 2012 um 23:12 Uhr


  • Der größte Wert, den ein 16-Bit-Ganzzahl ohne Vorzeichen enthalten kann, ist 65535, nicht 65536. Ein kleiner, aber wichtiger Unterschied, da 65536 dasselbe ist wie 0 in einem 16-Bit-Ganzzahl ohne Vorzeichen.

    – Sie Raybould

    10. Dezember 2013 um 23:00 Uhr

  • @gnasher729: Bist du dir bezüglich des C++-Standards sicher? Nachdem ich einige Zeit gesucht habe, habe ich den Eindruck, dass sie einfach alle absoluten Garantien für ganzzahlige Bereiche (außer unsigned char). Der Standard scheint die Zeichenfolge „65535“ oder „65536“ nirgendwo zu enthalten, und „+32767“ kommt nur in einer Note als (1,9:9) vor möglich größte darstellbare ganze Zahl in int; auch dafür wird keine Garantie gegeben INT_MAX kleiner geht nicht!

    – Marc van Leeuwen

    15. Juni 2014 um 7:38 Uhr

Der Typ size_t ist der Typ, der vom Operator sizeof zurückgegeben wird. Es ist eine Ganzzahl ohne Vorzeichen, die die Größe in Bytes eines beliebigen Speicherbereichs ausdrücken kann, der auf dem Hostcomputer unterstützt wird. Es ist (typischerweise) mit ptrdiff_t verwandt, da ptrdiff_t ein ganzzahliger Wert mit Vorzeichen ist, sodass sizeof(ptrdiff_t) und sizeof(size_t) gleich sind.

Beim Schreiben von C-Code sollten Sie immer Verwenden Sie size_t, wenn Sie mit Speicherbereichen arbeiten.

Der int-Typ hingegen ist im Wesentlichen als die Größe des (vorzeichenbehafteten) ganzzahligen Werts definiert, den der Hostcomputer verwenden kann, um ganzzahlige Arithmetik am effizientesten durchzuführen. Beispielsweise wäre auf vielen älteren PC-Computern der Wert sizeof(size_t) 4 (Byte), aber sizeof(int) wäre 2 (Byte). 16-Bit-Arithmetik war schneller als 32-Bit-Arithmetik, obwohl die CPU einen (logischen) Speicherplatz von bis zu 4 GiB verarbeiten konnte.

Verwenden Sie den int-Typ nur, wenn Sie Wert auf Effizienz legen, da seine tatsächliche Genauigkeit stark von den Compileroptionen und der Maschinenarchitektur abhängt. Insbesondere spezifiziert der C-Standard die folgenden Invarianten: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long), was keine weiteren Beschränkungen für die tatsächliche Darstellung der Genauigkeit auferlegt, die dem Programmierer für jede von zur Verfügung steht diese primitiven Typen.

Hinweis: Dies ist NICHT dasselbe wie in Java (das tatsächlich die Bitgenauigkeit für jeden der Typen ‘char’, ‘byte’, ‘short’, ‘int’ und ‘long’ angibt).

Typ size_t muss groß genug sein, um die Größe aller möglichen Objekte zu speichern. Unsigned int muss diese Bedingung nicht erfüllen.

In 64-Bit-Systemen können int und unsigned int beispielsweise 32 Bit breit sein, aber size_t muss groß genug sein, um Zahlen größer als 4G zu speichern

  • “Objekt” ist die vom Standard verwendete Sprache.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    7. August 2010 um 18:28 Uhr

  • Ich denke size_t müsste nur so groß sein, wenn der Compiler einen Typ X akzeptieren könnte, so dass sizeof(X) einen Wert größer als 4G ergeben würde. Die meisten Compiler würden zB ablehnen typedef unsigned char foo[1000000000000LL][1000000000000LL]und selbst foo[65536][65536]; rechtmäßig zurückgewiesen werden könnten, wenn sie eine dokumentierte, durch die Umsetzung definierte Grenze überschreiten.

    – Superkatze

    28. März 2014 um 20:24 Uhr

  • @MattJoiner: Die Formulierung ist in Ordnung. „Objekt“ ist überhaupt nicht vage, sondern eher so definiert, dass es „Speicherbereich“ bedeutet.

    – Leichtigkeitsrennen im Orbit

    5. April 2015 um 1:18 Uhr

1647070813 323 unsigned int vs size t
Graeme Burke

Auch dieser Auszug aus dem glibc-Handbuch 0.02 könnte bei der Recherche zum Thema relevant sein:

Es gibt ein potenzielles Problem mit dem Typ size_t und Versionen von GCC vor Version 2.4. ANSI C erfordert, dass size_t immer ein Typ ohne Vorzeichen ist. Aus Gründen der Kompatibilität mit Header-Dateien bestehender Systeme definiert GCC size_t in stddef.h' to be whatever type the system'ssys/types.h’ definiert es als. Die meisten Unix-Systeme, die size_t in `sys/types.h’ definieren, definieren es als signierten Typ. Ein Teil des Codes in der Bibliothek hängt davon ab, dass size_t ein unsignierter Typ ist, und funktioniert nicht richtig, wenn er signiert ist.

Der Code der GNU-C-Bibliothek, der erwartet, dass size_t unsigniert ist, ist korrekt. Die Definition von size_t als signierter Typ ist falsch. Wir planen, dass GCC in Version 2.4 size_t immer als vorzeichenlosen Typ definiert und die fixincludes' script will massage the system'ssys/types.h“, um damit nicht in Konflikt zu geraten.

In der Zwischenzeit umgehen wir dieses Problem, indem wir GCC explizit anweisen, einen unsignierten Typ für size_t zu verwenden, wenn die GNU-C-Bibliothek kompiliert wird. `configure’ erkennt automatisch, welchen Typ GCC für size_t verwendet, um ihn bei Bedarf zu überschreiben.

  • “Objekt” ist die vom Standard verwendete Sprache.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    7. August 2010 um 18:28 Uhr

  • Ich denke size_t müsste nur so groß sein, wenn der Compiler einen Typ X akzeptieren könnte, so dass sizeof(X) einen Wert größer als 4G ergeben würde. Die meisten Compiler würden zB ablehnen typedef unsigned char foo[1000000000000LL][1000000000000LL]und selbst foo[65536][65536]; rechtmäßig zurückgewiesen werden könnten, wenn sie eine dokumentierte, durch die Umsetzung definierte Grenze überschreiten.

    – Superkatze

    28. März 2014 um 20:24 Uhr

  • @MattJoiner: Die Formulierung ist in Ordnung. „Objekt“ ist überhaupt nicht vage, sondern eher so definiert, dass es „Speicherbereich“ bedeutet.

    – Leichtigkeitsrennen im Orbit

    5. April 2015 um 1:18 Uhr

1647070814 865 unsigned int vs size t
StaceyGirl

Wenn mein Compiler auf 32 Bit eingestellt ist, size_t ist nichts anderes als eine Typedef für unsigned int. Wenn mein Compiler auf 64 Bit eingestellt ist, size_t ist nichts anderes als eine Typedef für unsigned long long.

  • Kann nur definiert werden als unsigned long für beide Fälle auf einigen Betriebssystemen.

    – StaceyGirl

    17. August 2018 um 20:50 Uhr

993050cookie-checkunsigned int vs. size_t

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy