Essayez 285212672ULL
; Si vous l'écrivez sans suffixe, vous trouverez que le compilateur le traite comme un entier normal. La raison pour laquelle cela fonctionne dans une variable est parce que l'entier est converti en unsigned long long
dans l'affectation, de sorte que la valeur passée à printf()
est le bon type.
Et avant de vous demander, non, le compilateur probablement n'est pas assez intelligent pour le comprendre de la "%llu
"dans la chaîne de format printf()
. Voilà un autre niveau d'abstraction. Le compilateur est responsable de la syntaxe du langage , printf()
sémantique ne font pas partie de la syntaxe, il est une fonction de bibliothèque d'exécution (pas différent vraiment de vos propres fonctions, sauf qu'il est inclus dans la norme).
Considérez le code suivant pour un int 32 bits et 64 -bit système long non signé:
#include <stdio.h>
int main (void) {
printf ("%llu\n",1,2);
printf ("%llu\n",1ULL,2);
return 0;
}
qui fournit en sortie:
8589934593
1
Dans le premier cas, les deux entiers de 32 bits 1 et 2 sont poussés sur la pile et printf()
interprète cela comme une seule valeur ULL 64 bits, 2 x 2 + 1. L'argument 2
est inclus par inadvertance dans la valeur ULL.
Dans la seconde, vous appuyez réellement sur la valeur 1 de 64 bits et un entier de 32 bits superflus 2
, qui est ignoré. Notez que ce «désynchronisation» entre votre chaîne de format et vos arguments actuels est une mauvaise idée. Quelque chose comme:
printf ("%llu %s %d\n", 0, "hello", 0);
est susceptible de tomber en panne parce que le pointeur de 32 bits "hello"
sera consommé par le %llu
et %s
va essayer de de référence l'argument 0
final. L'image suivante illustre cela (supposons que les cellules sont de 32 bits et que la chaîne "hello" est stockée à 0xbf000000.
What you pass Stack frames What printf() uses
+------------+
0 | 0 | \
+------------+ > 64-bit value for %llu.
"hello" | 0xbf000000 |/
+------------+
0 | 0 | value for %s (likely core dump here).
+------------+
| ? | value for %d (could be anything).
+------------+
mais je pense que le compilateur est assez intelligent pour comprendre% u dans printf format spec, try printf ("% d% u", ~ 0, ~ 0) .. les deux vont imprimer les valeurs comme prévu .. – sud03r
Non - ces types de données sont de la même taille - c'est printf() % d avec 'a'. – paxdiablo
Pax: C'est bien aussi, les littéraux de caractère sont des constantes entières. – caf