Le compilateur décide de la taille des types de base et de la disposition des structures. Si une bibliothèque déclare des types, elle décidera de la manière dont ceux-ci sont définis et donc de leur taille.
Cependant, il arrive souvent que la compatibilité avec une norme existante et la nécessité de se lier à des bibliothèques existantes produites par d'autres compilateurs obligent une implémentation donnée à faire certains choix. Par exemple, la norme de langage stipule qu'un wchar_t
doit être plus large que 16 bits, et sur Linux, il est de 32 bits, mais il a toujours été de 16 bits sur Windows, de sorte que les compilateurs pour Windows choisissent tous d'être compatibles avec l'API Windows au lieu de la norme du langage. Une grande partie du code hérité, tant pour Linux que pour Windows, suppose qu'un fichier de type long
est exactement de 32 bits de large, tandis que d'autres codes supposaient qu'il était assez large pour contenir un horodatage en secondes ou une adresse IPv4 ou un offset de fichier ou les bits d'un pointeur, et (après qu'un compilateur ait défini int
comme une largeur de 64 bits et long
comme une largeur de 32 bits), la norme linguistique a établi une nouvelle règle selon laquelle int
ne peut être plus large que long
.
En conséquence, les compilateurs courants de ce siècle choisissent de définir int
comme une largeur de 32 bits, mais historiquement, certains l'ont définie comme une largeur de 16 bits, 18 bits, 32 bits, 64 bits et d'autres tailles. Certains compilateurs vous laissent choisir si long
sera d'une largeur de 32 bits exactement, comme le suppose certains codes hérités, ou aussi large qu'un pointeur, comme le suppose d'autres codes hérités.
Cela montre comment les hypothèses que vous faites aujourd'hui, comme le fait qu'un type soit toujours de 32 bits de large, peuvent se retourner contre vous à l'avenir. Cela est déjà arrivé deux fois aux bases de code C, lors des transitions vers le code 32 bits et 64 bits.
Mais qu'est-ce que vous devriez vraiment utiliser ?
El int
est rarement utile de nos jours. Il existe généralement un autre type que vous pouvez utiliser et qui garantit davantage ce que vous obtiendrez. (Il y a un avantage : les types qui ne sont pas aussi larges qu'une variable de type int
pourrait être automatiquement élargi à int
ce qui pourrait provoquer quelques bogues vraiment bizarres lorsque vous mélangez des types signés et non signés et int
est le plus petit type dont on garantit qu'il ne sera pas plus court que int
.)
Si vous utilisez une API particulière, vous voudrez généralement utiliser le même type qu'elle. Il existe de nombreux types dans la bibliothèque standard destinés à des fins spécifiques, tels que clock_t
pour les tics d'horloge et time_t
pour le temps en secondes.
Si vous voulez le type le plus rapide qui a une largeur d'au moins 16 bits, c'est int_fast16_t
et il existe d'autres types similaires. (Sauf indication contraire, tous ces types sont définis dans le document <stdint.h>
.) Si vous voulez le plus petit type qui a au moins 32 bits de large, pour mettre le plus de données dans vos tableaux, c'est int_least32_t
. Si vous voulez le type le plus large possible, c'est intmax_t
. Si vous savez que vous voulez exactement 32 bits, et votre compilateur a un type comme ça c'est int32_t
Si vous voulez quelque chose qui a une largeur de 32 bits sur une machine 32 bits et de 64 bits sur une machine 64 bits, et toujours la bonne taille pour stocker un pointeur, c'est intptr_t
. Si vous voulez un bon type pour faire de l'indexation de tableau et des calculs de pointeurs, c'est ptrdiff_t
de <stddef.h>
. (Celui-ci est dans un en-tête différent car il provient de C89 et non de C99).
Utilisez le type que vous voulez vraiment !
47 votes
Le processeur exécute le code machine, il ne décide rien.
0 votes
Je me suis dit qu'un @StoryTeller s'intéresserait à l'épistémologie :-)
3 votes
"Supposons que mon processeur puisse exécuter des applications 32 bits et 64 bits, qui jouera le rôle principal dans la décision de la taille des données, le compilateur ou le processeur ?" Le nombre de bits que votre CPU supporte ou non n'a aucune importance. Une fois que l'application est compilée, la taille est "intégrée dans les fichiers binaires de l'application". pour ainsi dire . Si votre processeur ne peut pas traiter le binaire, l'application ne peut pas fonctionner.
0 votes
@Prof.Falken - LOL. Eh bien, cela semblait approprié :)
0 votes
Je ne suis pas un expert dans ce domaine, mais dans le cas de WoW64, ne s'agit-il pas simplement d'émuler les binaires 32 bits vers 64 bits ? Donc, techniquement, il charge toujours certaines choses en 64 bits, mais les affiche en 32 bits ou quelque chose comme ça pour l'application ?
0 votes
@CraigYoung, c'est un angle de la question que je n'avais pas envisagé. Bon commentaire, il profitera aux futurs spectateurs de cette question.
1 votes
Notez également le
int
n'a pas vraiment besoin de se préoccuper de l'architecture du processeur. Un int 32 bits fonctionne bien en utilisant la moitié des bits disponibles dans un registre 64 bits. De même, les int 64 bits peuvent être émulés assez facilement sur les processeurs 32 bits. La seule chose qui n'est pas aussi flexible, cependant, est la taille d'un pointeur. Et même là, le OS peut permettre à des applications 32 bits de fonctionner sur des CPU 64 bits NB : Notez que la taille d'un pointeur n'est pas nécessairement la même que celle d'un int.1 votes
@Neijwiert, ce qui se passe est que lorsque Windows 64 bits voit un binaire 32 bits, il lance WoW64, qui est essentiellement toutes les DLLs du système Windows, mais dans des versions 32 bits. Ainsi, une installation 64 bits de Windows possède deux versions de presque tout. Il en va de même pour de nombreux systèmes Linux 64 bits, et je suppose, pour les Macs.
0 votes
@Prof.Falken C'est vrai, mais il ne peut pas exécuter les instructions x86 en une seule fois, n'est-ce pas ?
1 votes
@Neijwiert, en fait oui, ce qui se passe, et qui est vraiment cool, c'est que les CPU 64 bits (Intel/AMD) peuvent changer de mode à la volée de manière très efficace entre l'exécution en mode 32 bits (héritée) et en mode 64 bits. Voir aussi stackoverflow.com/a/20885980/193892
1 votes
stackoverflow.com/questions/2331751/ --- bien expliqué ici je suppose.
3 votes
Voir aussi modèle de données unix et linux ilp32 lp64 . Le système UNIX -- 64 bits et la neutralité de la taille des données est une très bonne lecture.
1 votes
Voir aussi, La taille d'un int dépend-elle du compilateur et/ou du processeur ? , Selon la norme C++, quelle doit être la taille des types int et long ?
1 votes
Prof. Falken - Dans l'un de vos commentaires, vous avez cité Commentaires en format Markdown . Celle qui commence par , _ce qui se passe, c'est que..._ Je ne comprends pas bien le lien.
0 votes
La taille de l'int n'est certainement pas nécessairement de 8 octets sur une plateforme 64 bits. Elle l'est pour gcc x64, mais pas pour toutes les plateformes de la même version du compilateur gcc, sans parler des autres compilateurs. Si vous supposez cela, vous aurez des problèmes. Si vous avez besoin de quelque chose d'assez large pour un pointeur, il y a size_t
0 votes
@jww, j'ai vu que tu as tapé <strike>quelque chose</strike>.
0 votes
Il existe un type pour maintenir (potentiellement) un pointeur, il s'écrit
uintptr_t
ou quelque chose comme ça.