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.

Justicle
quelle
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.

Ameise
quelle
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
14
#define MAZ_SZ (~(size_t)0)

oder SIZE_MAX

nategoose
quelle
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()
Kalmiya
quelle
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;
Prätorianer
quelle
13
Sollte ich das jemals in einem Code finden (besonders ohne Kommentar), würde es mich sehr mürrisch machen. :)
Craig McQueen