web-dev-qa-db-fra.com

Puis-je supposer que la taille de long int est toujours de 4 octets?

Est-il toujours vrai que long int (qui, autant que je sache, est synonyme de long) est 4 octets?

Puis-je compter sur cela? Sinon, cela pourrait-il être vrai pour un système d'exploitation basé sur POSIX?

70
Elimination

Les standards ne disent rien sur la taille exacte des types entiers mis à part char. Généralement, long est 32 bits sur les systèmes 32 bits et 64 bits sur les systèmes 64 bits.

La norme spécifie toutefois une taille minimum. À partir de la section 5.2.4.2.1 de la norme C :

1 Les valeurs indiquées ci-dessous doivent être remplacées par des expressions constantes utilisables dans #if directives de prétraitement. De plus, à l'exception de CHAR_BIT et MB_LEN_MAX, les éléments suivants doivent être remplacés par des expressions du même type qu’une expression qui est un objet du type correspondant converti en fonction des promotions d’entier. Leurs valeurs définies par la mise en oeuvre doivent être égales ou supérieures en magnitude (valeur absolue) à celles indiquées, avec le même signe.

...

  • valeur minimale pour un objet de type long int

    LONG_MIN -2147483647 // - (2 ^ 31−1)

  • valeur maximale pour un objet de type long int

    LONG_MAX +2147483647 // 2 ^ 31−1

Ceci dit qu'un long int must 32 bits minimum, mais peut être plus volumineux. Sur une machine où CHAR_BIT est 8, cela donne une taille d’octet minimale de 4. Cependant, sur une machine avec par ex. CHAR_BIT égal à 16, un long int pourrait durer 2 octets.

Voici un exemple du monde réel. Pour le code suivant:

#include <stdio.h>

int main ()
{
    printf("sizeof(long) = %zu\n", sizeof(long));
    return 0;
}

Sortie sur Debian 7 i686:

sizeof (long) = 4

Sortie sur CentOS 7 x64:

sizeof (long) = 8

Donc non, vous ne pouvez faire aucune hypothèse sur la taille. Si vous avez besoin d’un type de taille spécifique, vous pouvez utiliser les types définis dans stdint.h. Il définit les types suivants:

  • int8_t: signé 8 bits
  • uint8_t: non signé 8 bits
  • int16_t: signé 16 bits
  • uint16_t: non signé 16 bits
  • int32_t: signé 32 bits
  • uint32_t: non signé 32 bits
  • int64_t: signé 64 bits
  • uint64_t: non signé 64 bits

Le stdint.h en-tête est décrit à la section 7.20 de la norme et les types de largeur exacts à la section 7.20.1.1. La norme indique que ces typedefs sont facultatifs, mais ils existent dans la plupart des implémentations.

106
dbush

Non, ni la norme C ni POSIX ne le garantissent et en fait la plupart des plates-formes 64 bits de type Unix ont un format 64 bits (8 octets) long.

38
user395760

Utilisez le code sizeof(long int) et vérifiez la taille. Cela vous donnera la taille de long int en octets sur le système sur lequel vous travaillez actuellement. La réponse à votre question est en particulier NON. Cela n’est garanti nulle part en C, en POSIX ou ailleurs.

20
Kevin Pandya

Comme l'a souligné @delnan, les implémentations POSIX conservent la taille non spécifiée de long et int, qui diffère souvent entre les systèmes 32 bits et 64 bits.

La longueur de long est principalement liée à matériel (correspondant souvent à la taille des registres de données de la CPU et parfois à d’autres problèmes logiciels, tels que la conception du système d’exploitation et l’interfaçage ABI).

Pour soulager votre esprit, sizeof n'est pas une fonction, mais une directive de compilation *, de sorte que votre code n'utilise pas d'opérations lorsque vous utilisez sizeof - c'est la même chose que d'écrire un nombre, mais seulement portable.

utilisation:

sizeof(long int)

* Comme Dave l'a souligné dans les commentaires, sizeof sera calculé au moment de l'exécution lorsqu'il sera impossible de calculer la valeur lors de la compilation, par exemple lors de l'utilisation de tableaux de longueur variable.

De plus, comme indiqué dans un autre commentaire, sizeof prend en compte le remplissage et l'alignement utilisés par l'implémentation, ce qui signifie que les octets réellement utilisés pourraient être différents de la taille en mémoire (cela pourrait être important lors du décalage de bits ).

Si vous recherchez des variables de la taille d'un octet, envisagez d'utiliser un tableau d'octets ou (je suppose supposé être pris en charge) les types définis par C99 dans stdint.h - comme suggéré par @dbush.

14
Myst

Lorsque nous avons implémenté C pour la première fois le matériel ICL série 39, nous avons pris le standard au format Word et mappé les types de données sur la représentation naturelle de l'architecture de cette machine, à savoir short = 32 bits, int = 64 bits, long = 128 bits.

Mais nous avons constaté qu'aucune application C sérieuse ne fonctionnait; ils ont tous assumé le mappage short = 16, int = 32, long = 64, et nous avons dû changer le compilateur pour le supporter.

Ainsi, quoi que dise la norme officielle, depuis de nombreuses années tout le monde a convergé sur long = 64 bits et il est peu probable que cela change.

13
Michael Kay

Le standard ne dit rien sur la taille de long int, il dépend donc de l’environnement que vous utilisez.

Pour obtenir la taille de long int sur votre environnement, vous pouvez utiliser l’opérateur sizeof et obtenir la taille de long int. Quelque chose comme

sizeof(long int)

La norme C exige seulement les points suivants concernant les tailles de types

  • int> = 16 bits,
  • long> = 32 bits,
  • long long (depuis C99)> = 64 bits
  • sizeof (char) <= sizeof (court) <= sizeof (int) <= sizeof (long) <= sizeof (long long)
  • sizeof (char) == 1
  • CHAR_BIT> = 8

Le reste étant des implémentations définies, il n'est donc pas surprenant que l'on rencontre des systèmes où int a 18/24/36/60 bits, sa forme signée en complément, sizeof (char) == sizeof (short) == sizeof (int) == sizeof (long) == 4, 48 bits de long ou 9 bits tels que des architectures exotiques qui intéressent les comités de normalisation et une liste des plates-formes supportées par le standard C

Le point à propos de long int ci-dessus est complètement faux. La plupart des implémentations Linux/Unix définissent longtemps comme un type 64 bits, mais ce n’est que 32 bits dans Windows car ils utilisent des modèles de données différents (consultez le tableau ci-dessous informatique 64 bits ), et c’est indépendamment de la version 32 ou 64 bits du système d'exploitation.

Source

10
Rahul Tripathi

Le compilateur détermine la taille en fonction du type de matériel et du système d'exploitation.

Donc, les hypothèses ne devraient pas être faites concernant la taille.

8
Karthik Balaguru

De Blog de Usrmisc:

La norme la laisse complètement au compilateur, ce qui signifie également que le même compilateur peut le faire dépendre des options et de l'architecture cible.

Donc vous ne pouvez pas.

Incidemment long int est identique à long.

1
simhumileco

Réponse courte: non! Vous ne pouvez pas émettre d'hypothèses fixes sur la taille de long int. En effet, le standard (standard C ou POSIX) ne documente pas la taille de long int (Comme souligné à plusieurs reprises). Juste pour fournir un exemple contre vous, la plupart des systèmes 64 bits ont long de taille 64! Pour maximiser la portabilité, utilisez sizeof de manière appropriée.

Utilisez sizeof(long int) pour vérifier la taille, il renvoie la taille de long en octets. La valeur dépend du système ou de l'environnement. Cela signifie que le compilateur détermine la taille en fonction du matériel et du système d'exploitation.

0
Ehsan