Was ist eine tragbare Methode, um den Maximalwert von size_t zu ermitteln?


74

Ich möchte den Maximalwert von size_t auf dem System wissen, auf dem mein Programm ausgeführt wird. Mein erster Instinkt war, negative 1 zu verwenden, wie folgt:

size_t max_size = (size_t)-1;

Aber ich vermute, es gibt einen besseren Weg oder eine Konstante, die irgendwo definiert ist.


2
Das ist ein sehr kluger Trick, den Sie dort haben. +1!
Mhmmd

Ja, was du hast, ist in Ordnung (du brauchst die Besetzung übrigens nicht).
Stephen Canon

2
@Craig: Ein möglicher Grund könnte sein, dies als ungültigen Wert für eine size_tTypvariable festzulegen . Zum Beispiel std::string::nposist auf (size_t)-1(zumindest in der MSVC-Implementierung) gesetzt.
Prätorianer

1
Kann jemand erklären, was size_t max_size = (size_t)-1;eigentlich macht und wie? Vielen Dank.
Kolyunya

4
size_tist ein vorzeichenloser Typ gemäß dem Standard. Angenommen, es ist als 32-Bit-Wert definiert. Ein -1 wird als 0xffffffff für einen vorzeichenbehafteten Wert unter Verwendung des Zweierkomplements dargestellt. Wenn wir dies jedoch in size_t umwandeln, was ein vorzeichenloser Typ ist, ist es stattdessen der Maximalwert. (size_t)(-1)ist das gleiche wie (size_t)(0xffffffff)auf einem 32-Bit-System. Es ist besser, -1 zu verwenden, da dies auch bei 16-Bit (0xffff) oder 64-Bit funktioniert.
Joakim

Antworten:


70

In C99 existiert eine Manifestkonstante (ein Makro), die aufgerufen wird SIZE_MAX. In C89 / 90 gibt es jedoch keine solche Konstante.

Was Sie jedoch in Ihrem ursprünglichen Beitrag haben, ist eine perfekt tragbare Methode, um den Maximalwert von zu ermitteln size_t. Es funktioniert garantiert mit jedem nicht signierten Typ.


Vielen Dank, mein Compiler benötigt die Umwandlung, oder es wird eine Warnung über einen Vorzeichenwechsel während einer Ganzzahlkonvertierung ausgegeben.
Justicle

8
@jamesdlin: Die Konvertierung von vorzeichenbehaftet in vorzeichenlos ist in C immer gut definiert. Es ist erforderlich, die Regeln der typischen vorzeichenlosen Modulo-Arithmetik zu befolgen, wobei modulo gleich dem größten Wert des vorzeichenlosen Zieltyps plus 1 ist Fall werden Sie bekommen -1 mod (<max-value> + 1), was immer gerecht ist <max-value>.
Am

6
@jamesdlin: §5.2.4.2.1 garantiert, dass -1als dargestellt werden kann int. §6.3.1.3 garantiert, dass es in einen gültigen size_tWert konvertiert wird.
Stephen Canon

1
@jamesdlin: Eine andere Möglichkeit, dies zu sehen, ist size_tein vorzeichenloser Typ, sodass alle Werte gültig sind. Dies kann keine Trap-Darstellung sein, da es keine solche Trap gibt.
Jens Gustedt

1
@jamesdlin: ja, vorzeichenlose Typen sind wirklich einfältig ;-) von " 6.2.6.2 Integer types": If there are N value bits, each bit shall represent a different power of 2 between 1 and 2^N−1..Für vorzeichenlose Ganzzahltypen sind also wirklich keine Überraschungen möglich.
Jens Gustedt


5

Als Alternative zu den in den anderen Antworten vorgeschlagenen Bitoperationen können Sie dies in C ++ tun

#include <limits>
size_t maxvalue = std::numeric_limits<size_t>::max()

1
std::numeric_limits<size_t>::max()ist kein a constexprund wird von einigen Compilern wie Clang nicht gut optimiert. GCC, ICC und MSC handhaben das gut. Es ist oft besser, bei der zu bleiben #define.
JWW

3
@jww Es sollte eine constexprVersion von max()verfügbar sein: en.cppreference.com/w/cpp/types/numeric_limits/max
underscore_d

4

Die size_t max_size = (size_t)-1;vom OP vorgeschlagene Lösung ist definitiv die bisher beste, aber ich habe einen anderen, komplizierteren Weg gefunden, dies zu tun. Ich poste es nur aus akademischen Gründen.

#include <limits.h>

size_t max_size = ((((size_t)1 << (CHAR_BIT * sizeof(size_t) - 1)) - 1) << 1) + 1;

13
Sollte ich das jemals in einem Code finden (besonders ohne Kommentar), würde es mich sehr mürrisch machen. :)
Craig McQueen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.