web-dev-qa-db-fra.com

<cstdint> vs <stdint.h>

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 le intX_t/uintX_t types (où X est la taille en octets du type).

  • Si la logique dans les deux en-têtes est la même (types portables), quelles décisions dois-je prendre pour choisir l'un ou l'autre?

Le stdint.h définit chaque type sans espace de noms, les types cstdint se trouvent dans l’espace de noms std.

  • Existe-t-il une raison d'inclure ou non les types définis dans l'espace de noms std? Quelle est la différence entre les deux en-têtes?

cstdint n'a pas d'extension de fichier et utilise le préfixe c, stdint.h utilise le .h _ extension.

  • Quelles sont les conventions de dénomination pour ces en-têtes? le préfixe c indique qu'il s'agit d'une bibliothèque C? il y a une raison pour le manque d'extension de fichier dans cstdint?
77
PaperBirdMaster

L'intention initiale en C++ 98 était que vous deviez utiliser <cstdint> En C++, pour éviter de polluer l'espace de noms global (enfin, pas <cstdint> En particulier, cela n'a été ajouté qu'en C++ 11, mais les en-têtes <c*> en général).

Cependant, les implémentations ont quand même persisté à placer les symboles dans l'espace de noms global, et C++ 11 a ratifié cette pratique [*]. Donc, vous avez essentiellement trois options:

  • Utilisez <cstdint> Et qualifiez complètement chaque type d’entier que vous utilisez ou mettez-le dans le champ d’application avec using std::int32_t; Etc (ennuyeux parce que verbeux, mais c’est la bonne façon de le faire comme pour tout autre symbole la bibliothèque standard C++)
  • Utilisez <stdint.h> (Légèrement mauvais parce que déconseillé)
  • Utilisez <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 dérangeante utilise la dernière option, tout simplement parce qu’il est facile de le faire par accident sur une implémentation où <cstdint> Place les symboles dans l’espace de noms global. Vous devriez essayer d'utiliser le premier. La seconde a une vertu, c’est garanti de mettre des éléments dans l’espace de noms global au lieu de les faire peut-être uniquement. Je ne pense pas que cela soit particulièrement utile, mais cela pourrait vous éviter de taper si c'est votre priorité.

Il y a une quatrième option, #include <cstdint> Suivie de using namespace std; Qui est parfois utile, mais il y a des endroits où vous ne devriez pas mettre le using namespace std;. Différentes personnes auront des idées différentes quant à l'emplacement de ces lieux, mais "au plus haut niveau dans un fichier d'en-tête" est pire que "au plus haut niveau dans un fichier cpp", ce qui est pire que "dans un champ limité". Certaines personnes n'écrivent jamais using namespace std;.

[*] Cela signifie que les en-têtes standard C++ sont autorisés à placer des éléments dans l'espace de noms global, sans y être obligés. Vous devez donc éviter les collisions 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 presque aussi nuisibles que de coller using namespace std; Au plus haut niveau 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 , alors que using namespace std; le fait aussi pour les symboles uniquement C++. Il existe 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.

105
Steve Jessop

Inclure cstdint importe les noms de symbole dans un espace de noms std et éventuellement dans un espace de noms global.
Comprenant stdint.h importe les noms de symboles dans l’espace de noms global et éventuellement dans l’espace de noms std.

Des fonctionnalités de la bibliothèque standard C sont également fournies dans la bibliothèque standard C++. En règle générale, elles sont préfixées par un c aux noms correspondants dans la bibliothèque standard C.

En C++, vous devriez utiliser:

#include <cstdint>

et qualifiez pleinement les noms de symboles que vous utilisez avec std::
en C, vous devriez utiliser:

#include <stdint.h>

Annexe D (normative) Caractéristiques de compatibilité [depr] déclare:

en-têtes de bibliothèque standard D.6 C

1 Pour assurer la compatibilité avec la bibliothèque standard C et le C Unicode TR, la bibliothèque standard C++ fournit les en-têtes 25 C, comme indiqué dans le tableau 151.

Qui inclut:

<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h><complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h><ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h><errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h><fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

Et plus loin,

2 Chaque en-tête C, dont chacun porte un nom de la forme name.h, se comporte comme si chaque nom placé dans l’espace de nom de la bibliothèque standard par le cname header est placé dans la portée de l’espace de noms global. Il n’est pas précisé si ces noms sont d’abord déclarés ou définis dans la portée de l’espace de noms (3.3.6) de l’espace de noms std, puis sont injectés dans la portée de l’espace de noms global de manière explicite (7.3.3).

3 [Exemple: l'en-tête <cstdlib> fournit assurément ses déclarations et définitions dans l’espace de noms std. Il peut également fournir ces noms dans l'espace de noms global. L'en-tête <stdlib.h> fournit assurément les mêmes déclarations et définitions dans l’espace de noms global, à peu près comme dans la norme C. Il peut également fournir ces noms dans l'espace de noms std. —Fin exemple]

14
Alok Save
  1. cstdint est l'en-tête C++ 11, stdint.h est l'en-tête C99 (C et C++ sont des langages différents!)

  2. MSVC 2008 ne contient ni l'un ni l'autre stdint.h ni cstdint.

  3. Les implémentations de cstdint sont généralement simplement #include <stdint.h> avec des corrections d’espace de nom/langue.

0
hate-engine