Ce sont les options du compilateur qui définissent l'architecture sur laquelle va être portée le programme, mais en compilant pour amd64, la valeur renvoyée par sizeof devient un long unsigned int.
La différence est dans l'adressage (8 octets au lieu de 4 octets) mais aussi dans la taille des différents types
1 2 3 4 5 6 7 8 9 10
| TaillesEntiersAMD64.c :
la taille d'un char est de 1 octets
la taille d'un short est de 2 octets
la taille d'un int est de 4 octets
la taille d'un long int est de 8 octets
la taille d'un long long int est de 8 octets
la taille d'un float est de 4 octets
la taille d'un double est de 8 octets
la taille d'un long double est de 16 octets
la taille d'un size_t est de 8 octets |
1 2 3 4 5 6 7 8 9 10 11
|
TailleEntiersi386.c:
la taille d'un char est de 1 octets
la taille d'un short est de 2 octets
la taille d'un int est de 4 octets
la taille d'un long int est de 4 octets
la taille d'un long long int est de 8 octets
la taille d'un float est de 4 octets
la taille d'un double est de 8 octets
la taille d'un long double est de 12 octets
la taille d'un size_t est de 4 octets |
[EDIT](NB: je n'avais pas vu la réponse précédente. Est ce qui est entre [edit][/edit] correspond à ce que vous vouliez dire?)
Il y a un problème par exemple dans les lignes du genre
printf("la taille d'un size_t est de %ld octets\n",sizeof(size_t));
. (je ne saurai pas étendre la démonstration, pas assez de connaissance du C) si je fais
gcc -o ./a.out -pedantic -Wall -Wextra -march=k8 -mtune=i386 -m32 TailleEntiersAMD64.c
, J'ai l'avertissement suivant :
TailleEntiersAMD64.c:16: attention : format ‘%ld’ expects type ‘long int’, but argument 2 has type ‘unsigned int’
. Est-ce qu'il faudrait remplacer le type du format de sortie par une macro pour avoir un code portable et maintenable autrement que par la fonction "remplacer" des éditeurs de texte ?
1 2 3 4 5 6
|
#if ARCH == AMD64
#define SIZEOF_OUT "%ld"
#elif ARCH == i386
#define SIZEOF_OUT "%d"
#endif |
Je crois qu'il faudrai écrire le programme avec :
printf("la taille d'un size_t est de SIZEOF_OUT octets\n",sizeof(size_t));
pour éviter les erreurs de compilation et les warnings. Ça sûrement à voir avec le makefile et le ./configure, bien que je ne m'y connaisse pas trop.
Ça donne sûrement une idée de ce qu'il ne faut pas faire pour écrire du code portable, mais c'est une question d'expert un peu. Je me demande par exemple si faire des casts est une bonne manière d'écrire un code portable.[/EDIT]
On remarque que les tailles des types "simples" (short, char, int, float, double) ne changent pas, seulement celles des pointeurs et des types strictement calculatoires du genre long long int et long double (long double sur 128 bits pour AMD64 donc deux registres du processeur, contre long double sur 96 bits pour i386, ce qui fait 3*32 bits=trois registres processeurs). Ça donne une certaine idée des optimisations de calcul possibles avec le processeur AMD64.
gcc -o ./a.out -pedantic -Wall -Wextra -march=i386 -m32
signifie une compilation pour le jeu d'instructions i386 avec des instructions 32 bits
gcc -o ./a.out -pedantic -Wall -Wextra -march=k8 -m64
signifie une compilation pour l'architecture k8 (AMD64) avec un jeu d'instructions 64 bits.
Partager