Wo finde ich die Definition von size_t?


123

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 .
Dan Nissenbaum

Antworten:


122

Aus Wikipedia

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.

Ab C99 7.17.1 / 2

Die folgenden Typen und Makros sind im Standardheader definiert stddef.h

<Snip>

size_t

Dies ist der vorzeichenlose Ganzzahltyp des Ergebnisses des Operators sizeof


2
Zum Beispiel auf Win64, intund unsigned intTypen sind 32 Bits, während size_t 64 Bits.
Michael Burr

7
Bitte beziehen Sie sich auf den ISO C (99) -Standard (aus dem der C ++ - Standard stammt), Abschnitte 7.17 und 7.18.3
Martin York,

3
@LokiAstari warum bearbeitest du nicht einfach die Antwort, da du weißt, wo sie im Standard geschrieben ist?
Hi-Angel

Wo ist also die C ++ - Antwort?
Lothar

@ Lothar Ich denke, der einzige Unterschied ist, dass size_t ein Schlüsselwort sein kann und ansonsten die gleiche Bedeutung hat.
Paul Stelian

30

Entsprechend der Beschreibung von size_t auf en.cppreference.com size_t wird in den folgenden Headern definiert:

std::size_t

...    

Defined in header <cstddef>         
Defined in header <cstdio>      
Defined in header <cstring>         
Defined in header <ctime>       
Defined in header <cwchar>

2
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.)


Die beste Antwort, da sie den Standard zitiert.
Martin York

1
@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.


2

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.

Die eigentliche Definition finden Sie in der C ++ - Referenzbibliothek , in der Folgendes steht:

Art: size_t (vorzeichenloser Integraltyp)

Header: <cstring>

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.


2

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.


1

Ich bin nur mit dem void_tErgebnis einer Google-Suche vertraut (sie wird in einer vmallocBibliothek 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:

  • 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.)


1

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.

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.