Ich sehe Variablen, die mit diesem Typ definiert wurden, aber ich weiß nicht, woher er kommt und wozu er dient. Warum nicht int oder unsigned int verwenden? (Was ist mit anderen "ähnlichen" Typen? Void_t usw.).
@kjfletch: hhhmmm, es ist seltsam, dass die Suche nach dem Begriff 'size_t' (wie ich es zuvor getan habe) diese Frage nicht zurückgegeben hat.
Eliseo Ocampos
1
@Eliseo - Die Suchfunktion von Stackoverflow ist schrecklich. Verwenden Sie stattdessen Google mit dem Parameter "site: stackoverflow.com".
Michael Burr
8
Das OP fragte speziell Wo finde ich die Definition von size_t? Ich bin hier gelandet und habe nach dem gleichen gesucht. Der zitierte Dup diskutiert nicht, wo die Erklärung zu finden ist.
JWW
9
Diese Frage ist offensichtlich nicht die gleiche wie die verknüpfte. "Wo finde ich etwas ? " Ist nicht dasselbe wie "Was ist der Unterschied zwischen" (selbst wenn die Antwort auf die eine die Antwort auf die andere liefert). Meine Google-Suche nach "c ++ wo ist size_t definition" hat mich direkt hierher geführt, und ich hätte die andere Frage verpasst, weil sie anders ist .
Die Dateien stdlib.hund stddef.hheader definieren einen Datentyp namens size_t1, der zur Darstellung der Größe eines Objekts verwendet wird. Bibliotheksfunktionen, die Größen annehmen, erwarten, dass sie vom Typ sind size_t, und der Operator sizeof wird ausgewertetsize_t .
Der tatsächliche Typ von size_tist plattformabhängig; ein häufiger Fehler ist , anzunehmen , size_tdie gleiche wie unsigned int ist, die Programmierfehler führen kann, 2 insbesondere als 64-Bit - Architekturen häufiger geworden.
Dies ist genau das, was ich brauchte, diese Antwort sollte positiv bewertet werden.
Neodelphi
27
size_t ist der vorzeichenlose Integer-Typ des Ergebnisses des Operators sizeof (ISO C99, Abschnitt 7.17.)
Der sizeofOperator gibt die Größe (in Bytes) seines Operanden an, der ein Ausdruck oder der Name eines Typs in Klammern sein kann. Die Größe wird aus dem Typ des Operanden bestimmt. Das Ergebnis ist eine Ganzzahl. Der Wert des Ergebnisses ist implementierungsdefiniert und sein Typ (ein vorzeichenloser Integer-Typ) ist size_t(ISO C99 Abschnitt 6.5.3.4.)
@Martin - stimmt, aber ich denke, dass der Teil "Warum ist nicht vorzeichenlos int verwendet" der Frage genauso interessant (oder mehr) ist wie der Teil "Was ist size_t", und das finden Sie nicht im Standard .
Michael Burr
Ja, außer es gibt keinen 'Abschnitt 17.17 ': p. Es ist selten, niemand sagte ein Wort über Void_t
Eliseo Ocampos
Ich akzeptiere diese Antwort, da sie direkt auf die Frage antwortet, aber es wäre großartig, wenn sie mit Michaels Antwort ergänzt würde.
Eliseo Ocampos
58
Schade, dass Ihre Antwort mir nicht sagt, welche Header-Datei enthalten sein soll.
Matt
6
Praktisch size_trepräsentiert die Anzahl der Bytes, die Sie adressieren können. Bei den meisten modernen Architekturen waren dies in den letzten 10 bis 15 Jahren 32 Bit, was auch die Größe eines vorzeichenlosen Int hatte. Wir uintwechseln jedoch zur 64-Bit-Adressierung, während die wahrscheinlich bei 32 Bit bleibt (die Größe wird im c ++ - Standard nicht garantiert). Um Ihren Code, der von der Speichergröße abhängt, über Architekturen portierbar zu machen, sollten Sie a verwenden size_t. Zum Beispiel sollten Dinge wie Arraygrößen immer size_t's verwenden. Wenn Sie sich die Standardcontainer ansehen, wird ::size()immer a zurückgegebensize_t .
Beachten Sie auch, dass Visual Studio über eine Kompilierungsoption verfügt, mit der nach solchen Fehlern gesucht werden kann, die als "64-Bit-Portabilitätsprobleme erkennen" bezeichnet werden.
Auf diese Weise wissen Sie immer, wie groß die Größe ist, da ein bestimmter Typ den Größen zugeordnet ist. Die eigene Frage zeigt, dass es sich um ein Problem handeln kann: Ist es ein intoder ein unsigned int? Auch, was die Größe ( short, int,long , etc.)?
Da ein bestimmter Typ zugewiesen ist, müssen Sie sich keine Gedanken über die Länge oder die Signatur machen.
size_tentspricht dem vom Sprachoperator zurückgegebenen integralen Datentyp sizeofund ist in der definiert<cstring> Header-Datei (unter anderem) als vorzeichenloser integraler Typ definiert.
In <cstring>wird es als Typ des Parameters numin den Funktionen verwendet memchr.memcmp , memcpy, memmove, memset, strncat, strncmp, strncpyundstrxfrm , die in allen Fällen wird es verwendet , um die maximale Anzahl von Bytes oder Zeichen angeben , die Funktion zu beeinflussen hat.
Es wird auch als Rückgabetyp für strcspn,, verwendet strlen.strspn und strxfrmauf Rückkehr Größen und Längen.
size_t sollte in den Headern Ihrer Standardbibliothek definiert sein. Nach meiner Erfahrung ist es normalerweise einfach ein typedef für unsigned int. Der Punkt ist jedoch, dass es nicht sein muss. Mit Typen wie size_t kann der Standardbibliotheksanbieter die zugrunde liegenden Datentypen gegebenenfalls für die Plattform ändern. Wenn Sie davon ausgehen, dass size_t immer int ohne Vorzeichen ist (über Casting usw.), können in Zukunft Probleme auftreten, wenn Ihr Anbieter size_t in einen 64-Bit-Typ ändert. Aus diesem Grund ist es gefährlich, irgendetwas über diesen oder einen anderen Bibliothekstyp anzunehmen.
Die verschiedenen xxede_t-Typedefs werden verwendet, um einen Typ von einer bestimmten bestimmten Implementierung zu abstrahieren, da die für bestimmte Dinge verwendeten konkreten Typen von Plattform zu Plattform unterschiedlich sein können. Beispielsweise:
size_t abstrahiert den Typ, der zum Speichern der Größe von Objekten verwendet wird, da dies auf einigen Systemen ein 32-Bit-Wert ist, auf anderen ein 16-Bit- oder 64-Bit-Wert.
Void_tabstrahiert den Zeigertyp, der von den vmallocBibliotheksroutinen zurückgegeben wird, da er für die Arbeit auf Systemen geschrieben wurde, die vor ANSI / ISO C erstellt wurdenvoid Schlüsselwort möglicherweise nicht vorhanden ist. Zumindest würde ich das vermuten.
wchar_t abstrahiert den Typ, der für breite Zeichen verwendet wird, da es sich auf einigen Systemen um einen 16-Bit-Typ handelt, auf anderen um einen 32-Bit-Typ.
Wenn Sie also Ihren Code für die Verarbeitung breiter Zeichen schreiben, um den wchar_tTyp anstelle von beispielsweise zu verwenden, unsigned shortist dieser Code vermutlich für verschiedene Plattformen portabler.
Dies ist, wonach ich teilweise gesucht habe. Wie ich in einem Kommentar in der Antwort von fpmurphy sagte, wäre es großartig, wenn es mit dieser Antwort ergänzt werden könnte (Wenn es Ihnen nichts ausmacht, können Sie sie vielleicht bearbeiten) :)
Eliseo Ocampos
1
In minimalistischen Programmen, in denen eine size_tDefinition in einigen Include nicht "zufällig" geladen wurde, ich sie aber in einem bestimmten Kontext noch benötige (zum Beispiel für den Zugriff std::vector<double>), verwende ich diesen Kontext, um den richtigen Typ zu extrahieren. Beispielsweisetypedef std::vector<double>::size_type size_t .
( namespace {...}Bei Bedarf mit umgeben, um den Umfang einzuschränken.)
Wie für "Warum nicht int oder unsigned int verwenden?", Einfach weil es semantisch sinnvoller ist, dies nicht zu tun. Es gibt den praktischen Grund, dass es typedefbeispielsweise als intund dann als longspäter aktualisiert werden kann , ohne dass jemand seinen Code ändern muss, aber grundlegender als das, dass ein Typ sinnvoll sein soll. Um dies erheblich zu vereinfachen, ist eine Variable vom Typ size_tfür die Größe von Dingen geeignet und wird für diese verwendet, genau wie time_tfür die Aufnahme von Zeitwerten. Wie diese tatsächlich implementiert werden, sollte die Aufgabe der Implementierung sein. Im Vergleich dazu, einfach alles intaufzurufen, hilft die Verwendung aussagekräftiger Typnamen wie dieser dabei, die Bedeutung und Absicht Ihres Programms zu verdeutlichen, genau wie es jeder umfangreiche Satz von Typen tut.
Antworten:
Aus Wikipedia
Ab C99 7.17.1 / 2
quelle
int
undunsigned int
Typen sind 32 Bits, während size_t 64 Bits.Entsprechend der Beschreibung von size_t auf en.cppreference.com
size_t
wird in den folgenden Headern definiert:quelle
size_t
ist der vorzeichenlose Integer-Typ des Ergebnisses des Operators sizeof (ISO C99, Abschnitt 7.17.)Der
sizeof
Operator gibt die Größe (in Bytes) seines Operanden an, der ein Ausdruck oder der Name eines Typs in Klammern sein kann. Die Größe wird aus dem Typ des Operanden bestimmt. Das Ergebnis ist eine Ganzzahl. Der Wert des Ergebnisses ist implementierungsdefiniert und sein Typ (ein vorzeichenloser Integer-Typ) istsize_t
(ISO C99 Abschnitt 6.5.3.4.)quelle
Praktisch
size_t
repräsentiert die Anzahl der Bytes, die Sie adressieren können. Bei den meisten modernen Architekturen waren dies in den letzten 10 bis 15 Jahren 32 Bit, was auch die Größe eines vorzeichenlosen Int hatte. Wiruint
wechseln jedoch zur 64-Bit-Adressierung, während die wahrscheinlich bei 32 Bit bleibt (die Größe wird im c ++ - Standard nicht garantiert). Um Ihren Code, der von der Speichergröße abhängt, über Architekturen portierbar zu machen, sollten Sie a verwendensize_t
. Zum Beispiel sollten Dinge wie Arraygrößen immersize_t
's verwenden. Wenn Sie sich die Standardcontainer ansehen, wird::size()
immer a zurückgegebensize_t
.Beachten Sie auch, dass Visual Studio über eine Kompilierungsoption verfügt, mit der nach solchen Fehlern gesucht werden kann, die als "64-Bit-Portabilitätsprobleme erkennen" bezeichnet werden.
quelle
Auf diese Weise wissen Sie immer, wie groß die Größe ist, da ein bestimmter Typ den Größen zugeordnet ist. Die eigene Frage zeigt, dass es sich um ein Problem handeln kann: Ist es ein
int
oder einunsigned int
? Auch, was die Größe (short
,int
,long
, etc.)?Da ein bestimmter Typ zugewiesen ist, müssen Sie sich keine Gedanken über die Länge oder die Signatur machen.
Die eigentliche Definition finden Sie in der C ++ - Referenzbibliothek , in der Folgendes steht:
quelle
size_t sollte in den Headern Ihrer Standardbibliothek definiert sein. Nach meiner Erfahrung ist es normalerweise einfach ein typedef für unsigned int. Der Punkt ist jedoch, dass es nicht sein muss. Mit Typen wie size_t kann der Standardbibliotheksanbieter die zugrunde liegenden Datentypen gegebenenfalls für die Plattform ändern. Wenn Sie davon ausgehen, dass size_t immer int ohne Vorzeichen ist (über Casting usw.), können in Zukunft Probleme auftreten, wenn Ihr Anbieter size_t in einen 64-Bit-Typ ändert. Aus diesem Grund ist es gefährlich, irgendetwas über diesen oder einen anderen Bibliothekstyp anzunehmen.
quelle
Ich bin nur mit dem
void_t
Ergebnis einer Google-Suche vertraut (sie wird in einervmalloc
Bibliothek von Kiem-Phong Vo bei AT & T Research verwendet - ich bin sicher, dass sie auch in anderen Bibliotheken verwendet wird).Die verschiedenen xxede_t-Typedefs werden verwendet, um einen Typ von einer bestimmten bestimmten Implementierung zu abstrahieren, da die für bestimmte Dinge verwendeten konkreten Typen von Plattform zu Plattform unterschiedlich sein können. Beispielsweise:
Void_t
abstrahiert den Zeigertyp, der von denvmalloc
Bibliotheksroutinen zurückgegeben wird, da er für die Arbeit auf Systemen geschrieben wurde, die vor ANSI / ISO C erstellt wurdenvoid
Schlüsselwort möglicherweise nicht vorhanden ist. Zumindest würde ich das vermuten.wchar_t
abstrahiert den Typ, der für breite Zeichen verwendet wird, da es sich auf einigen Systemen um einen 16-Bit-Typ handelt, auf anderen um einen 32-Bit-Typ.Wenn Sie also Ihren Code für die Verarbeitung breiter Zeichen schreiben, um den
wchar_t
Typ anstelle von beispielsweise zu verwenden,unsigned short
ist dieser Code vermutlich für verschiedene Plattformen portabler.quelle
In minimalistischen Programmen, in denen eine
size_t
Definition in einigen Include nicht "zufällig" geladen wurde, ich sie aber in einem bestimmten Kontext noch benötige (zum Beispiel für den Zugriffstd::vector<double>
), verwende ich diesen Kontext, um den richtigen Typ zu extrahieren. Beispielsweisetypedef std::vector<double>::size_type size_t
.(
namespace {...}
Bei Bedarf mit umgeben, um den Umfang einzuschränken.)quelle
Wie für "Warum nicht int oder unsigned int verwenden?", Einfach weil es semantisch sinnvoller ist, dies nicht zu tun. Es gibt den praktischen Grund, dass es
typedef
beispielsweise alsint
und dann alslong
später aktualisiert werden kann , ohne dass jemand seinen Code ändern muss, aber grundlegender als das, dass ein Typ sinnvoll sein soll. Um dies erheblich zu vereinfachen, ist eine Variable vom Typsize_t
für die Größe von Dingen geeignet und wird für diese verwendet, genau wietime_t
für die Aufnahme von Zeitwerten. Wie diese tatsächlich implementiert werden, sollte die Aufgabe der Implementierung sein. Im Vergleich dazu, einfach allesint
aufzurufen, hilft die Verwendung aussagekräftiger Typnamen wie dieser dabei, die Bedeutung und Absicht Ihres Programms zu verdeutlichen, genau wie es jeder umfangreiche Satz von Typen tut.quelle