printf with sizeof sur 32 vs 64 plates-formes: comment gérer le code de format indépendamment de la plate-forme?

StackOverflow https://stackoverflow.com/questions/1403074

  •  05-07-2019
  •  | 
  •  

Question

J'ai un code qui imprime la quantité de mémoire utilisée par le programme. La ligne ressemble à ceci:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

où anIntVariable est une variable int pour le nombre d'éléments du tableau double. De toute façon, sur les systèmes 32 bits, je n’ai jamais eu de problèmes, mais sur les systèmes 64 bits, je reçois un avertissement du compilateur concernant l’utilisation de "% u". pour un entier long non signé. Utilisation de "% lu " car le code de format corrige le problème sur 64 bits, mais amène le compilateur à se plaindre sur 32 bits, car le type est de nouveau défini sur unsigned int. J'ai constaté qu'en effet, sizeof (double) renvoie une valeur différente sur les systèmes 32 vs 64 bits. J'ai trouvé des guides de page Web pour convertir le code de 32 bits à 64 bits.

Comment puis-je écrire cette ligne de manière indépendante de la plate-forme? Je connais de nombreuses façons de le faire en utilisant des directives de pré-traitement, mais cela semble être un bidouillage. Il y a sûrement une manière élégante que je ne réalise pas.

Était-ce utile?

La solution

Les identificateurs portables printf sont fournis dans le fichier d'inclusion inttypes.h .

Ce fichier d'inclusion contient de nombreux identifiants portables pour votre environnement d'exécution spécifique. Pour votre exemple, vous voulez PRIuPTR, ce qui signifie " PR " si I dentifier u est signé avec une taille pouvant aller jusqu'à celle d'un pointeur ".

Votre exemple sera alors:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

Résultats sous Linux 64 bits avec GCC 4.3 ( int anIntVariable = 1 ):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

Par souci d'exhaustivité, il existe également des identifiants pour scanf, dont les préfixes sont SCN.

Autres conseils

La valeur de retour de sizeof est un size_t. Si vous utilisez un compilateur compatible C99, il semble que vous puissiez utiliser % zd % zu pour cela.

D'oh: % zu (non signé) bien sûr. Merci beaucoup.

Tout d’abord, vous devez faire correspondre le "% " spécificateur avec le type de données que vous souhaitez imprimer. sizeof renvoie le type de données size_t . De même, vous ne devez pas essayer d'imprimer un fichier flottant à l'aide du "% d " spécificateur, vous ne devriez pas essayer d’imprimer un size_t avec "% u " ou "% d " ou tout ce qui ne signifie pas vraiment size_t.

Les autres réponses ont donné de bons moyens de gérer cela avec les nouveaux compilateurs ("% z" et PRIu32), mais nous avions l'habitude de faire cela simplement en convertissant size_t en unsigned long, puis en l'imprimant avec "% lu":

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

Cela ne fonctionnera pas sur les systèmes où size_t est plus large que long, mais je ne connais aucun système de ce type, et je ne suis même pas sûr que la norme le permette.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top