Quelle est la différence entre un int et un long en C ++?

Corrigez-moi si je me trompe,

int est de 4 octets, avec une plage de valeurs allant de -2 147 483 648 à 2 147 483 647 (2 ^ 31)
long est de 4 octets, avec une plage de valeurs allant de -2 147 483 648 à 2 147 483 647 (2 ^ 31)

Quelle est la différence en C ++? Peuvent-ils être utilisés indifféremment?

Cela dépend de la mise en œuvre.

Par exemple, sous Windows, ils sont identiques, mais par exemple, sur les systèmes Alpha, il y avait 64 bits, alors que l’int était 32 bits. Cet article couvre les règles du compilateur Intel C ++ sur les plates-formes variables. Résumer:

  OS arch size Windows IA-32 4 bytes Windows Intel 64 4 bytes Windows IA-64 4 bytes Linux IA-32 4 bytes Linux Intel 64 8 bytes Linux IA-64 8 bytes Mac OS X IA-32 4 bytes Mac OS X Intel 64 8 bytes 

La seule garantie que vous avez est:

 sizeof(char) == 1 sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) // FROM @KTC. The C++ standard also has: sizeof(signed char) == 1 sizeof(unsigned char) == 1 // NOTE: These size are not specified explicitly in the standard. // They are implied by the minimum/maximum values that MUST be supported // for the type. These limits are defined in limits.h sizeof(short) * CHAR_BIT >= 16 sizeof(int) * CHAR_BIT >= 16 sizeof(long) * CHAR_BIT >= 32 sizeof(long long) * CHAR_BIT >= 64 CHAR_BIT >= 8 // Number of bits in a byte 

Voir aussi: Est-ce que long garanti a au moins 32 bits?

Lors de la compilation pour x64, la différence entre int et long se situe entre 0 et 4 octets, selon le compilateur que vous utilisez.

GCC utilise le modèle LP64, ce qui signifie que les ints sont en 32 bits mais que les longues sont en 64 bits en mode 64 bits.

MSVC, par exemple, utilise le modèle LLP64, ce qui signifie que les deux ints et les longs sont 32 bits, même en mode 64 bits.

La spécification C ++ elle-même (ancienne version, mais suffisante pour cela) laisse cela ouvert.

Il existe quatre types d’entiers signés: ‘ signed char ‘, ‘ short int ‘, ‘ int ‘ et ‘ long int ‘. Dans cette liste, chaque type fournit au moins autant de stockage que ceux qui le précèdent dans la liste. Plain ints a la taille naturelle suggérée par l’architecture de l’environnement d’exécution *;

[Note de bas de page: c’est-à-dire suffisamment grande pour contenir toute valeur dans la plage INT_MIN et INT_MAX, telle que définie dans l’en-tête . — fin foonote]

Comme le souligne Kevin Haines, Ints a la taille naturelle suggérée par l’environnement d’exécution, qui doit tenir dans INT_MIN et INT_MAX.

La norme C89 stipule que UINT_MAX doit être au moins 2 ^ 16-1, USHRT_MAX 2 ^ 16-1 et ULONG_MAX 2 ^ 32-1. Cela fait un nombre de bits d’au moins 16 pour short et int et 32 ​​pour longtemps. Pour char, il est explicitement indiqué qu’il doit avoir au moins 8 bits ( CHAR_BIT ). C ++ hérite de ces règles pour le fichier limits.h. En C ++, nous avons les mêmes exigences fondamentales pour ces valeurs. Vous ne devriez cependant pas en déduire qu’int est au moins de 2 octets. Théoriquement, char, int et long peuvent tous être de 1 octet, auquel cas CHAR_BIT doit être au moins 32. Rappelez-vous juste que “byte” a toujours la taille d’un caractère, donc si char est plus grand, un octet n’est pas seulement 8 bits plus

Cela dépend de votre compilateur. Vous avez la garantie qu’un long sera au moins aussi grand qu’un int, mais vous n’êtes pas certain que ce sera plus long.

Pour la plupart, le nombre d’octets et la plage de valeurs sont déterminés par l’architecture du processeur et non par C ++. Cependant, C ++ établit des exigences minimales, ce qui a été expliqué correctement et Martin York n’a fait que quelques erreurs.

La raison pour laquelle vous ne pouvez pas utiliser int et de manière interchangeable est parce qu’ils ne sont pas toujours de la même longueur. C a été inventé sur un PDP-11 où un octet avait 8 bits, int était deux octets et pouvait être géré directement par des instructions matérielles. Étant donné que les programmeurs C ont souvent besoin d’une arithmétique sur quatre octets, long a été inventé et il s’agissait de quatre octets, gérés par les fonctions de la bibliothèque. Les autres machines avaient des spécifications différentes. La norme C imposait des exigences minimales.

S’appuyant sur l’implémentation des tailles de type primitives par le fournisseur du compilateur, vous reviendrez vous hanter si vous comstackz votre code sur une autre architecture de machine, un système d’exploitation ou un compilateur d’un autre fournisseur.

La plupart des fournisseurs de compilateurs fournissent un fichier d’en-tête qui définit les types primitifs avec des tailles de type explicites. Ces types primitifs doivent être utilisés chaque fois que le code est potentiellement porté sur un autre compilateur (lisez ceci comme TOUJOURS dans chaque instance). Par exemple, la plupart des compilateurs UNIX ont int8_t uint8_t int16_t int32_t uint32_t . Microsoft a INT8 UINT8 INT16 UINT16 INT32 UINT32 . Je préfère int8 uint8 int16 uint16 int32 uint32 Borland / CodeGear. Ces noms rappellent également un peu la taille / plage de la valeur souhaitée.

Pendant des années, j’ai utilisé les noms de types primitifs explicites de Borland et #include le fichier d’en-tête C / C ++ suivant (primitive.h) destiné à définir les types primitifs explicites avec ces noms pour tout compilateur C / C ++. couvre tous les compilateurs mais couvre plusieurs compilateurs que j’ai utilisés sous Windows, UNIX et Linux, mais ne définit pas (encore) les types 64 bits).

 #ifndef primitiveH #define primitiveH // Header file primitive.h // Primitive types // For C and/or C++ // This header file is intended to define a set of primitive types // that will always be the same number bytes on any operating operating systems // and/or for several popular C/C++ comstackr vendors. // Currently the type definitions cover: // Windows (16 or 32 bit) // Linux // UNIX (HP/US, Solaris) // And the following comstackr vendors // Microsoft, Borland/Imprise/CodeGear, SunStudio, HP/UX // (maybe GNU C/C++) // This does not currently include 64bit primitives. #define float64 double #define float32 float // Some old C++ comstackrs didn't have bool type // If your comstackr does not have bool then add emulate_bool // to your command line -D option or defined macros. #ifdef emulate_bool # ifdef TVISION # define bool int # define true 1 # define false 0 # else # ifdef __BCPLUSPLUS__ //BC++ bool type not available until 5.0 # define BI_NO_BOOL # include  # else # define bool int # define true 1 # define false 0 # endif # endif #endif #ifdef __BCPLUSPLUS__ # include  #else # ifdef unix # ifdef hpux # include  # endif # ifdef sun # include  # endif # ifdef linux # include  # endif # define int8 int8_t # define uint8 uint8_t # define int16 int16_t # define int32 int32_t # define uint16 uint16_t # define uint32 uint32_t # else # ifdef _MSC_VER # include  # define int8 INT8 # define uint8 UINT8 # define int16 INT16 # define int32 INT32 # define uint16 UINT16 # define uint32 UINT32 # else # ifndef OWL6 // OWL version 6 already defines these types # define int8 char # define uint8 unsigned char # ifdef __WIN32_ # define int16 short int # define int32 long # define uint16 unsigned short int # define uint32 unsigned long # else # define int16 int # define int32 long # define uint16 unsigned int # define uint32 unsigned long # endif # endif # endif # endif #endif typedef int8 sint8; typedef int16 sint16; typedef int32 sint32; typedef uint8 nat8; typedef uint16 nat16; typedef uint32 nat32; typedef const char * cASCIIz; // constant null terminated char array typedef char * ASCIIz; // null terminated char array #endif //primitive.h 

Le standard C ++ le dit ainsi:

3.9.1, §2:

Il existe cinq types entiers signés: “signé char”, “court int”, “int”, “long int” et “long long int”. Dans cette liste, chaque type fournit au moins autant de stockage que ceux qui le précèdent dans la liste. Plain ints a la taille naturelle suggérée par l’architecture de l’environnement d’exécution (44); les autres types d’entiers signés sont fournis pour répondre à des besoins spéciaux.

(44) c’est-à-dire suffisamment grand pour contenir n’importe quelle valeur dans l’intervalle INT_MIN et INT_MAX, comme défini dans l’en-tête .

La conclusion: cela dépend de l’architecture sur laquelle vous travaillez. Toute autre hypothèse est fausse.