Was ist der Unterschied zwischen stdint.h
und cstdint
?
Beide sind in MSVC (Visual Studio 2010) und gcc-4.5.1 verfügbar. Außerdem definieren beide die intX_t
/ uintX_t
-Typen (wobei X
die Größe des Typs in Bytes ist).
- Wenn die Gründe in beiden Headern gleich sind (tragbare Typen), welche Entscheidungen muss ich treffen, um mich für den einen oder anderen zu entscheiden?
Das stdint.h
definiert jeden Typ ohne Namespace, der cstdint
Typ liegt im std
Namespace.
- Gibt es einen Grund, die definierten Typen in den
std
Namespace aufzunehmen oder nicht aufzunehmen ? Was ist zwischen den beiden Headern unterschiedlich?
cstdint
hat keine Dateierweiterung und verwendet das c
Präfix, stdint.h
verwendet die .h
Erweiterung.
- Was sind die Namenskonventionen für diese Header? Das
c
Präfix gibt an, dass dies eine C-Bibliothek ist. Gibt es einen Grund für die fehlende Dateierweiterung incstdint
?
<cstdint>
. Hier ist der Fehler, den ich erhalte :./misc.h:7:10: fatal error: 'cstdint' file not found
.Antworten:
Die ursprüngliche Absicht in C ++ 98 war, dass Sie
<cstdint>
in C ++ verwenden sollten, um eine Verschmutzung des globalen Namespace zu vermeiden (nicht<cstdint>
speziell, das wird nur in C ++ 11 hinzugefügt, sondern die<c*>
Header im Allgemeinen).Die Implementierungen bestanden jedoch weiterhin darin, die Symbole in den globalen Namespace einzufügen, und C ++ 11 bestätigte diese Vorgehensweise [*]. Sie haben also grundsätzlich drei Möglichkeiten:
<cstdint>
Sie jeden von Ihnen verwendeten Integer-Typ und qualifizieren Sie ihn entweder vollständig oder bringen Sie ihn mitusing std::int32_t;
etc in den Geltungsbereich (ärgerlich, weil ausführlich, aber es ist der richtige Weg, dies wie bei jedem anderen Symbol in der C ++ - Standardbibliothek zu tun).<stdint.h>
(etwas schlecht, weil veraltet)<cstdint>
und nehmen Sie an, dass Ihre Implementierung die Symbole in den globalen Namespace einfügt (sehr schlecht, weil nicht garantiert).In der Praxis vermute ich, dass eine ärgerlich große Menge an Code die letzte Option verwendet, einfach weil es bei einer Implementierung, bei
<cstdint>
der die Symbole in den globalen Namespace eingefügt werden, einfach ist, dies versehentlich zu tun . Sie sollten versuchen, die erste zu verwenden. Die zweite hat eine Tugend, dass es garantiert ist , Dinge in den globalen Namespace zu stellen, anstatt es vielleicht nur zu tun. Ich denke nicht, dass dies besonders nützlich ist, aber es könnte einige Eingaben ersparen, wenn dies Ihre Priorität ist.Es gibt eine vierte Option,
#include <cstdint>
gefolgt vonusing namespace std;
der manchmal nützlich ist, aber es gibt Stellen, an denen Sie die nicht setzen solltenusing namespace std;
. Unterschiedliche Personen haben unterschiedliche Vorstellungen, wo sich diese Orte befinden, aber "auf oberster Ebene in einer Header-Datei" ist schlechter als "auf oberster Ebene in einer CPP-Datei", was schlechter ist als "in einem begrenzten Bereich". Manche Leute schreibenusing namespace std;
überhaupt nicht.[*] Das bedeutet, dass C ++ - Standardheader Inhalte in den globalen Namespace einfügen dürfen, dies jedoch nicht. Sie müssen also vermeiden, mit diesen Symbolen zu kollidieren, können sie jedoch nicht verwenden, da sie möglicherweise nicht vorhanden sind. Grundsätzlich ist der globale Namespace in C ++ ein Minenfeld. Versuchen Sie es zu vermeiden. Man könnte argumentieren, dass das Komitee eine Praxis durch Implementierungen ratifiziert hat, die fast so schädlich ist wie das Festhalten
using namespace std;
auf oberster Ebene in einer Header-Datei - der Unterschied besteht darin, dass die Implementierungen dies nur für Symbole in der C-Standardbibliothek tun, währendusing namespace std;
dies für C ++ der Fall ist -nur Symbole auch. Es gibt einen Abschnitt im C-Standard, in dem Namen aufgeführt sind, die für zukünftige Ergänzungen des Standards reserviert sind. Es ist keine völlig dumme Idee, diese Namen auch im globalen C ++ - Namespace als reserviert zu behandeln, aber es ist nicht unbedingt erforderlich.quelle
<iostream>
,<vector>
,<cstdlib>
, abgesehen von denen , die für C - Kompatibilität mit eingeschlossen:<stdint.h>
,<stdlib.h>
. Und ja, die Initialec
zeigt an, dass<cstdlib>
C ++ dem C-Standard-Header entspricht<stdlib.h>
, anstatt wie in C ++ völlig neu zu sein<vector>
. Es gibt einen C ++ - Header<complex>
, daher müssen wir nur hoffen, dass keine zukünftige Version von C einen Standardheader einführt<omplex.h>
.<omplex.h>
, nicht<complex.h>
. Wenn C hinzugefügt würde<omplex.h>
, wäre das C ++ - Äquivalent<complex>
.Einschließlich
cstdint
Importiert die Symbolnamen in den Standard-Namespace und möglicherweise in den globalen Namespace.Einschließlich
stdint.h
Importiert die Symbolnamen in den globalen Namespace und möglicherweise in den Standard-Namespace.Funktionen der C-Standardbibliothek sind auch in der C ++ - Standardbibliothek enthalten und werden als allgemeine Namenskonvention durch ein c an die entsprechenden Namen in der C-Standardbibliothek angehängt.
In C ++ sollten Sie Folgendes verwenden:
und qualifizieren Sie die Symbolnamen, mit denen Sie
std::
in C arbeiten, vollständig. Sie sollten Folgendes verwenden:
Anhang D (normativ) In den Kompatibilitätsmerkmalen heißt es:
D.6 C Standardbibliotheksheader
Die einschließen:
Und weiter,
quelle
cstdint
ist C ++ 11 Header,stdint.h
ist C99 Header (C und C ++ sind verschiedene Sprachen!)MSVC 2008 enthält weder
stdint.h
nochcstdint
.Implementierungen von
cstdint
sind meist einfach#include <stdint.h>
mit einigen Namespace- / Sprachkorrekturen.quelle
cstdint
muss die Implementierungen in den Namespace hebenstd
.stdint.h
. Es gibt kein Argument,cstdint
das ein C ++ - Header ist.stdint.h
es nicht Teil von C ++ 11 ist. Tatsächlich wird es von C ++ 11 benötigt. Man könnte sagen, "int
ist in C ++ 11;long
ist in C99; C und C ++ sind verschiedene Sprachen!", Und auch kein Teil davon wäre falsch. Mein Beispiel ist jedoch noch irreführender, da C ++ 11 teilweise auf C99 verweist, um den Inhalt von beiden zu definieren,stdint.h
undcstdint
nicht auf C, um zu definierenint
.