web-dev-qa-db-fra.com

impression multiplate-forme d'entiers 64 bits avec printf

Dans Windows, il s’agit de "% I64d". Dans Linux et Solaris, il s'agit de "% lld".
Si je veux écrire printfs multiplate-forme qui affiche les valeurs long long: quel est le bon moyen de le faire?

long long ll;
printf(???, ll);
23
Andrei

Il y a plusieurs approches.

Vous pouvez écrire votre code conformément au code C99, puis fournir des hacks spécifiques au système lorsque les auteurs du compilateur vous abandonnent. (Malheureusement, c'est assez courant en C99.)

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

Si l'un de vos systèmes cibles a négligé d'implémenter <inttypes.h> ou s'est relâché de façon diabolique parce que certaines des fonctionnalités de type sont facultatives, vous avez simplement besoin d'un #define spécifique au système pour PRId64 (ou autre) sur ce système.

L'autre approche consiste à choisir quelque chose qui est actuellement toujours implémenté en tant que 64 bits et qui est pris en charge par printf, puis converti. Pas parfait mais cela fera souvent:

printf("My value is %10lld\n", (long long)some_64_bit_expression);
37
DigitalRoss

MSVC prend en charge long long et ll à partir de Visual Studio 2005 .

Vous pouvez vérifier la valeur de la macro _MSC_VER (>= 1400 pour 2005) ou simplement ne pas prendre en charge les anciens compilateurs.

Il ne fournit pas les macros C99, vous devrez donc transtyper en long long plutôt que d'utiliser PRId64.

Cela ne vous aidera pas si vous utilisez d'anciennes bibliothèques MSVC avec un compilateur non-MSVC (je pense que mingw, au moins, fournit sa propre version de printf qui prend en charge ll)

2
Random832

Non sur linux et solaris, ce n'est qu'incidemment que c'est lld pour un type 64 bits. C99 préconise des macros simples (mais laides) pour rendre ces choses portables PRId64. Certains compilateurs de Windows ne respectant pas cette norme, vous n’auriez peut-être pas de chance, malheureusement.

Edit: Dans votre exemple, vous utilisez une autre chose qu'un entier 64 bits, à savoir un long long. Cela pourrait bien être 128 sur certaines architectures. Ici C99 a typedefs qui vous garantissent la largeur minimale ou exacte du type (s’ils sont implémentés sur la plate-forme). Ces types se trouvent dans l'en-tête inttypes.h, à savoir int64_t pour un type à largeur fixe de 64 bits représenté au complément à deux. Peut-être que votre compilateur Windows ne l’a peut-être pas.

1
Jens Gustedt

Comme alternative, vous pouvez utiliser un code comme celui-ci:

uint64_t currentTimeMs = ...;

printf("currentTimeMs = 0x%08x%08x\n",
            (uint32_t)(currentTimeMs >> 32),
            (uint32_t)(currentTimeMs & 0xFFFFFFFF)
    );

Ou peut-être:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );
0