Lorsque j’essaie d’assigner un entier de 128 bits dans gcc 4.9.1, un warning: integer constant is too large for its type
.
int main(void) { __uint128_t p = 47942806932686753431; return 0; }
Je comstack avec gcc -std=c11 -o test test.c
et je reçois:
test.c: In function 'main': test.c:2:19: warning: integer constant is too large for its type __uint128_t p = 47942806932686753431; ^
Est-ce que je fais quelque chose de mal ou est-ce un bug dans gcc?
Est-ce que je fais quelque chose de mal ou est-ce un bug dans gcc?
Le problème est dans 47942806932686753431
partie, pas dans __uint128_t p
. Selon gcc docs, il n’ya aucun moyen de déclarer une constante de 128 bits:
GCC ne prend pas en charge l’expression d’une constante entière du type __int128 pour les cibles dont l’entier long est inférieur à 128 bits.
Il semble donc que, bien que vous puissiez avoir des variables 128 bits, vous ne pouvez pas avoir de constantes 128 bits, sauf si votre long long
est long long
128 bits.
La solution de rechange pourrait consister à construire une valeur de 128 bits à partir de constantes intégrales “plus étroites” à l’aide d’opérations arithmétiques de base, en espérant que le compilateur effectue un repliement constant .
Avez-vous essayé cela?
__int128 p = *(__int128*) "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
EDIT le 25 novembre
Désolé pour la pauvre clarification sur le post précédent. Sérieusement, je n’ai pas posté cette réponse comme une blague. Bien que la documentation GCC indique qu’il n’ya aucun moyen d’exprimer une constante entière de 128 bits, cet article fournit simplement une solution de contournement à ceux qui souhaitent affecter facilement des valeurs à des variables __uint128_t.
Vous pouvez essayer de comstackr le code ci-dessous avec GCC (7.2.0) ou Clang (5.0.0). Il imprime les résultats souhaités.
#include #include int main() { __uint128_t p = *(__int128*) "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"; printf("HIGH %016llx\n", (uint64_t) (p >> 64)); printf("LOW %016llx\n", (uint64_t) p); return 0; }
La stdout:
HIGH 0f0e0d0c0b0a0908 LOW 0706050403020100
Ceci est seulement considéré comme une solution de contournement puisqu’il joue des astuces sur les pointeurs en plaçant la “valeur” dans la section .rodata (si vous l’objdumpez), et que ce n’est pas portable (x86_64 et aarch64 conviennent mais ne sont pas armés ni x86). Je pense que cela suffit pour le codage sur des ordinateurs de bureau.