Sélection de type “long” ou “long long” en tant que type 64 bits dans les modèles de données LP64 / ILP64 / LLP64?

J’essaie de comprendre les exigences relatives à la sélection d’un type de données 64 bits intégré en utilisant long ou long long . J’ai du mal à comprendre l’équivalence de type et les exigences d’alignement de long par rapport à long long .

Quelle est la meilleure pratique ou les meilleurs critères lors de la sélection de type long long long 64 bits avec les modèles de données LP64 / ILP64 / LLP64?


Voici quelques questions connexes. Ils couvrent complètement d’autres sujets, tels que sizeof(long) <= sizeof(long long) , mais ils ne traitent pas tout à fait des attentes d’équivalence ou d’alignement. Ils dépendent également fortement de types non intégrés, comme uint64_t .

  • Le système UNIX – Neutralité 64 bits et taille de données
  • Quelle est la différence entre unsigned long / long / int dans c / c ++?
  • Mieux vaut utiliser long ou long long en 64 bits
  • Spécification de littéraux entiers non signés 64 bits sur des modèles de données 64 bits

Les informations d’arrière-plan correspondent au code suivant pour sélectionner un type 64 bits intégré à utiliser:

 #if _LP64 || __LP64__ || _ILP64 || __ILP64__ typedef my_u64 unsigned long; #else typedef my_u64 unsigned long long; #endif 

i686 et ARMv7 et les typedef my_u64 unsigned long long conviennent bien avec typedef my_u64 unsigned long long .

Premier cas de problème

Sur un ordinateur x86_64 (AMD64), si typedef my_u64 unsigned long est typedef my_u64 unsigned long (en raison de LP64 ), il en résulte une erreur de compilation:

 $ gcc -mrdrnd test.cc -o test.exe test.cc: In function 'int main(int, char**)': test.cc:18:22: error: invalid conversion from 'my_u64* {aka long unsigned int*}' to 'long long unsigned int*' [-fpermissive] _rdrand64_step(&val); ^ In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86insortingn.h:46:0, from test.cc:2: /usr/lib/gcc/x86_64-linux-gnu/4.9/include/imminsortingn.h:166:1: note: initializing argument 1 of 'int _rdrand64_step(long long unsigned int*)' _rdrand64_step (unsigned long long *__P) ^ 

Deuxième problème

Sur un ordinateur Aarch64 (ARM64), si typedef my_u64 unsigned long long est en vigueur (pour corriger l’erreur x86_64), il en résulte une erreur de compilation:

 $ gcc test.cc -o test.exe test.cc: In function 'int main(int, char**)': test.cc:21:16: error: invalid conversion from 'my_u64* {aka long long unsigned int*}' to 'const uint64_t* {aka const long unsigned int*}' [-fpermissive] vld1q_u64(val); ^ In file included from test.cc:4:0: /usr/lib/gcc/aarch64-linux-gnu/4.9/include/arm_neon.h:17003:1: note: initializing argument 1 of 'uint64x2_t vld1q_u64(const uint64_t*)' vld1q_u64 (const uint64_t *a) ^ 

 $ cat test.cc #if __x86_64__ #include  #elif __aarch64__ #include  #include  #endif #if _LP64 || __LP64__ typedef unsigned long my_u64; #else typedef unsigned long long my_u64; #endif int main(int argc, char* argv[]) { #if __x86_64__ my_u64 val; _rdrand64_step(&val); #elif __aarch64__ my_u64 val[2]; vld1q_u64(val); #endif return 0; }