Laut cppreference.com size_t
ist in mehreren Headern nämlich definiert
<cstddef>
<cstdio>
<cstring>
<ctime>
Und seit C ++ 11 auch in
<cstdlib>
<cwchar>
Zunächst frage ich mich, warum dies der Fall ist. Steht dies nicht im Widerspruch zum DRY- Prinzip? Meine Frage ist jedoch:
Welchen der oben genannten Header sollte ich einschließen, um ihn zu verwenden size_t
? Ist das überhaupt wichtig?
<cstddef>
fürstd::size_t
std::size_t
gibt und das OP nicht befürwortete, ältere C-Funktionen zu verwenden, sondern nur das Zitat zu beachten, dass sie das typedef teilen. Ich bezweifle, dass jemand, der diesen Thread liest, aus diesem Grund in die Irre geführt wird, ältere Typen / Funktionen zu verwenden, aber wenn Sie sicher sein möchten, dass dies nicht der Fall ist, dann fair genug!Antworten:
Angenommen, ich wollte die Funktionen und Typen, die ich importierte, minimieren, würde ich gehen,
cstddef
da es keine Funktionen deklariert und nur 6 Typen deklariert. Die anderen konzentrieren sich auf bestimmte Domänen (Zeichenfolgen, Zeit, E / A), die für Sie möglicherweise nicht von Bedeutung sind.Beachten Sie, dass
cstddef
nur die Definitionstd::size_t
,size_t
dh die Definition im Namespacestd
, garantiert wird, obwohl dieser Name möglicherweise auch im globalen Namespace (effektiv, einfachsize_t
) bereitgestellt wird .Im Gegensatz dazu
stddef.h
garantiert (was auch ein in C verfügbarer Header ist), dass ersize_t
im globalen Namespace definiert wird, und kann auch bereitstellenstd::size_t
.quelle
size_t
fromcstddef
das gleiche ist und immer das gleiche sein wird wie die anderen? Es scheint, dass es eine gemeinsame Header-Datei mit gemeinsamen Definitionen wiesize_t
...cstddef
.<cstddef>
, oder sie können alle einen internen Header enthalten, der nur definiertsize_t
.csttddef
in der Antwort ein Tippfehler? Vielleichtcstddef
ist gemeint?Tatsächlich definiert die Zusammenfassung (im C ++ - Standard enthalten) mehrerer Header, die spezifisch enthalten sind
size_t
, sowie weitere Header den Typsize_t
(basierend auf dem C-Standard, da die<cX>
Header nur ISO C-<X.h>
Header mit angegebenen Änderungen sind, bei denen das Entfernensize_t
nicht angegeben ist).Der C ++ Standard jedoch bezieht sich auf
<cstddef>
die Definition vonstd::size_t
Daher und aufgrund der Tatsache, dass
<cstddef>
nur Typen und keine Funktionen eingeführt werden, würde ich mich an diesen Header halten, um ihnstd::size_t
verfügbar zu machen .Beachten Sie einige Dinge:
Die Art von
std::size_t
istdecltype
ohne Verwendung eines Headers erhältlichWenn Sie planen , eine typedef in Ihrem Code einzuführen sowieso (zB weil Sie schreiben einen Behälter und wollen die Bereitstellung eines
size_type
typedef) können Sie den globalen verwenden könnensizeof
,sizeof...
oderalignof
Betreiber Ihre Art zu definieren , ohne Header überhaupt einschließlich da theose Operatoren gebenstd::size_t
pro Standard Definition und Sie könnendecltype
auf ihnen verwenden:std::size_t
ist per se nicht global sichtbar, obwohl Funktionen mitstd::size_t
Argumenten sind.Die implizit deklarierten globalen Zuordnungs- und Freigabefunktionen
NICHT einführen
size_t
,std
oderstd::size_t
undDer Benutzer kann möglicherweise nicht neu definieren,
std::size_t
obwohl es möglich ist, mehrere Typedefs zu haben, die auf denselben Typ im selben Namespace verweisen.Obwohl das Auftreten mehrerer Definitionen von
size_t
innerhalbstd
gemäß 7.1.3 / 3 vollkommen gültig ist, dürfennamespace std
gemäß 17.6.4.2.1 / 1 keine Erklärungen hinzugefügt werden :Das Hinzufügen eines richtigen typedef für
size_t
zum Namespace verstößt nicht gegen 7.1.3 , aber gegen 17.6.4.2.1 und führt zu undefiniertem Verhalten.Erläuterung: Versuchen Sie, 7.1.3 nicht falsch zu interpretieren, und fügen Sie keine Deklarationen oder Definitionen hinzu
std
(mit Ausnahme einiger Fälle von Vorlagenspezialisierung, in denen ein typedef keine Vorlagenspezialisierung ist). Erweiterung dernamespace std
quelle
std
ungültig ist, da doppelte Typedefs illegal sind. Ich erkläre, dass es illegal ist, weil Sie einfach keine Definitionen hinzufügen dürfennamespace std
- egal ob sie legal wären.Alle Standard-Bibliotheksheaderdateien haben dieselbe Definition. Es spielt keine Rolle, welche Sie in Ihren eigenen Code aufnehmen. Auf meinem Computer habe ich die folgende Erklärung in
_stddef.h
. Diese Datei ist in jeder von Ihnen aufgelisteten Datei enthalten.quelle
size_t
?size_t
. Sie können es portabler definieren alsusing size_t = decltype( sizeof( 42 ) )
. Aber es gibt keine Notwendigkeit, da<stddef.h>
fast keine Kosten entstehen.Sie könnten auf einen Header verzichten:
Dies liegt daran, dass der C ++ - Standard Folgendes erfordert:
Mit anderen Worten, der Standard verlangt:
Beachten Sie auch, dass es vollkommen in Ordnung ist, diese
typedef
Deklaration im globalen und imstd
Namespace abzugeben , solange sie mit allen anderentypedef
Deklarationen desselben Typedef-Namens übereinstimmt (bei nicht übereinstimmenden Deklarationen wird ein Compilerfehler ausgegeben).Das ist weil:
§7.1.3.1 Ein typedef-Name führt keinen neuen Typ ein, wie es eine Klassendeklaration (9.1) oder eine Enum-Deklaration tut.
§7.1.3.3 In einem bestimmten Nichtklassenbereich
typedef
kann ein Bezeichner verwendet werden, um den Namen eines in diesem Bereich deklarierten Typs neu zu definieren, um auf den Typ zu verweisen, auf den er sich bereits bezieht.Für Skeptiker, die sagen, dass dies eine Hinzufügung eines neuen Typs zum Namespace darstellt
std
und eine solche Handlung durch den Standard ausdrücklich verboten ist, und dies ist UB und das ist alles da; Ich muss sagen, dass diese Haltung bedeutet, ein tieferes Verständnis der zugrunde liegenden Probleme zu ignorieren und zu leugnen.Der Standard verbietet das Hinzufügen neuer Deklarationen und Definitionen zum Namespace,
std
da der Benutzer auf diese Weise die Standardbibliothek durcheinander bringen und sein gesamtes Bein abschießen kann. Für die Standardautoren war es einfacher, den Benutzer auf einige bestimmte Dinge spezialisieren zu lassen und alles andere aus gutem Grund zu verbieten, als alles zu verbieten, was der Benutzer nicht tun sollte, und das Risiko einzugehen, etwas Wichtiges (und dieses Bein) zu verpassen. Sie haben dies in der Vergangenheit getan, als sie forderten, dass kein Standardcontainer mit einem unvollständigen Typ instanziiert werden soll, während dies tatsächlich einige Container tun könnten (siehe Der Standardbibliothekar: Container unvollständiger Typen von Matthew H. Austern ):Angesichts der Tatsache, dass die Sprachregeln
std::size_t
genau sein müssendecltype(sizeof(int))
, ist das Tunnamespace std { using size_t = decltype(sizeof(int)); }
eines der Dinge, die nichts kaputt machen.Vor C ++ 11 gab es keine
decltype
und daher keine Möglichkeit, die Art dessizeof
Ergebnisses in einer einfachen Anweisung zu deklarieren, ohne dass viele Vorlagen beteiligt waren.size_t
Aliase für verschiedene Typen auf verschiedenen Zielarchitekturen. Es wäre jedoch keine elegante Lösung, einen neuen integrierten Typ nur für das Ergebnis von hinzuzufügensizeof
, und es gibt keine standardmäßigen integrierten Typedefs. Daher bestand die portabelste Lösung zu dieser Zeit darin,size_t
Typalias in einen bestimmten Header einzufügen und diesen zu dokumentieren.In C ++ 11 gibt es jetzt eine Möglichkeit, die genaue Anforderung des Standards als eine einfache Deklaration aufzuschreiben.
quelle
size_t
!" Eine Minute später sagte Mary: "OMG! Es gibt 7 Definitionen fürsize_t
Standard-Bibliotheksheader und einen Projektheader, den Tom bearbeitet! Es gibt wahrscheinlich mehr in den Bibliotheken von Drittanbietern!" xkcd.com/927size_t
Dies ist zwar eine mögliche Definition von , beantwortet aber nicht die eigentliche Frage des OP: Es ist, als hätte ich nach dem Header gefragt, in demFILE
deklariert ist, und Sie würden vorschlagen, meinen eigenen zu schreiben.