Quelle est la différence entre stdint.h
et cstdint
?
Les deux sont disponibles dans MSVC (Visual Studio 2010) et gcc-4.5.1. Les deux définissent également les types intX_t
/ uintX_t
(où X
est la taille en octets du type).
- Si la justification dans les deux en-têtes est la même (types portables), quelles décisions dois-je prendre pour décider de l'un ou de l'autre?
Le stdint.h
définit chaque type sans aucun espace de noms, les cstdint
types se trouvent dans l' std
espace de noms.
- Y a-t-il une raison d'inclure ou de ne pas inclure les types définis dans l'
std
espace de noms? Quelle est la différence entre les deux en-têtes?
cstdint
n'a pas d'extension de fichier et utilise le c
préfixe, stdint.h
utilise l' .h
extension.
- Quelles sont les conventions de dénomination de ces en-têtes? le
c
préfixe indique qu'il s'agit d'une bibliothèque C? il y a une raison pour le manque d'extension de fichier danscstdint
?
<cstdint>
. Voici l'erreur que je reçois:./misc.h:7:10: fatal error: 'cstdint' file not found
.Réponses:
L'intention originale dans C ++ 98 était que vous devriez utiliser
<cstdint>
en C ++, pour éviter de polluer l'espace de noms global (enfin, pas<cstdint>
en particulier, cela n'est ajouté qu'en C ++ 11, mais les en-<c*>
têtes en général).Cependant, les implémentations ont persisté à placer les symboles dans l'espace de noms global de toute façon, et C ++ 11 a ratifié cette pratique [*]. Donc, vous avez essentiellement trois options:
<cstdint>
et qualifiez complètement chaque type d'entier que vous utilisez ou mettez-le dans la portée avecusing std::int32_t;
etc (ennuyeux car verbeux, mais c'est la bonne façon de le faire comme pour tout autre symbole de la bibliothèque standard C ++)<stdint.h>
(légèrement mauvaise car obsolète)<cstdint>
et supposez que votre implémentation placera les symboles dans l'espace de noms global (très mauvais car non garanti).En pratique, je soupçonne qu'une grande quantité de code ennuyeuse utilise la dernière option, simplement parce que c'est facile à faire par accident sur une implémentation où
<cstdint>
met les symboles dans l'espace de noms global. Vous devriez essayer d'utiliser le premier. Le second a une vertu, c'est qu'il est garanti de mettre des choses dans l'espace de noms global au lieu de le faire peut-être seulement. Je ne pense pas que ce soit particulièrement utile, mais cela pourrait vous faire gagner du temps si c'est votre priorité.Il y a une quatrième option,
#include <cstdint>
suivie deusing namespace std;
laquelle est parfois utile, mais il y a des endroits où vous ne devriez pas mettre le fichierusing namespace std;
. Différentes personnes auront des idées différentes où se trouvent ces endroits, mais «au niveau supérieur dans un fichier d'en-tête» est pire que «au niveau supérieur dans un fichier cpp», ce qui est pire que «dans une portée limitée». Certaines personnes n'écrivent jamaisusing namespace std;
du tout.[*] Cela signifie que les en-têtes standards C ++ sont autorisés à placer des éléments dans l'espace de noms global mais pas obligés de le faire. Vous devez donc éviter d'entrer en collision avec ces symboles, mais vous ne pouvez pas les utiliser car ils pourraient ne pas être là. Fondamentalement, l'espace de noms global en C ++ est un champ de mines, essayez de l'éviter. On pourrait soutenir que le comité a ratifié une pratique par des implémentations qui est presque aussi nuisible que de rester
using namespace std;
au niveau supérieur dans un fichier d'en-tête - la différence étant que les implémentations ne le font que pour les symboles de la bibliothèque standard C, alorsusing namespace std;
que pour C ++ -seulement symboles aussi. Il y a une section dans la norme C qui répertorie les noms réservés pour de futurs ajouts à la norme. Ce n'est pas une idée complètement stupide de traiter ces noms comme réservés dans l'espace de noms global C ++, mais ce n'est pas essentiel.la source
<iostream>
,<vector>
,<cstdlib>
, à l' exception de ceux qui sont inclus pour assurer la compatibilité C:<stdint.h>
,<stdlib.h>
. Et oui, l'initialec
indique que<cstdlib>
c'est l'équivalent en C ++ de l'en-tête standard C<stdlib.h>
, plutôt que d'être totalement nouveau en C ++ comme l'<vector>
est. Il y a un en-tête C ++<complex>
, donc nous devrons juste espérer qu'aucune future version de C n'introduira un en-tête standard<omplex.h>
.<omplex.h>
, non<complex.h>
. Si C ajouté<omplex.h>
, l'équivalent C ++ serait<complex>
.Y compris
cstdint
importe les noms de symboles dans l'espace de noms std et éventuellement dans l'espace de noms Global.Y compris
stdint.h
importe les noms de symboles dans l'espace de noms Global et éventuellement dans l'espace de noms std.Les fonctionnalités de la bibliothèque standard C sont également fournies dans la bibliothèque standard C ++ et en tant que convention de dénomination générale, elles sont précédées d'un c aux noms correspondants dans la bibliothèque standard C.
En C ++, vous devriez utiliser:
et qualifiez complètement les noms de symboles que vous utilisez avec
std::
en C, vous devez utiliser:
L'Annexe D (normative) Caractéristiques de compatibilité [depr] stipule:
D.6 En-têtes de bibliothèque standard C
Qui inclut:
Et plus loin,
la source
cstdint
est l'en-tête C ++ 11,stdint.h
est l'en-tête C99 (C et C ++ sont des langages différents!)MSVC 2008 ne contient ni
stdint.h
nicstdint
.Les implémentations de
cstdint
sont pour la plupart simplement#include <stdint.h>
avec quelques corrections d'espace de noms / de langue.la source
cstdint
doit hisser les implémentations dans l'espace de nomsstd
.stdint.h
. Il n'y a pas d'argument quicstdint
soit un en-tête C ++.stdint.h
ne pas faire partie de C ++ 11. En fait, il est requis par C ++ 11. Vous pourriez dire, "int
est en C ++ 11;long
est en C99; C et C ++ sont des langages différents!", Et aucune partie de cela ne serait fausse non plus. Mon exemple est encore plus trompeur, cependant, puisque C ++ 11 se réfère en partie à C99 pour définir le contenu des deuxstdint.h
etcstdint
, mais ne fait pas référence à C pour définirint
.