J'ai une question très précise. J'ai la macro suivante définie pour être utilisée dans le code plus tard.
x = 0x7766554433221100; y = 0xFFEEDDCCBBAA9988;
Maintenant, je veux inverser l'ordre pendant la compilation et générer une valeur à incorporer directement dans l'exécutable pendant la compilation. Donc, fondamentalement, je veux le code suivant
long x = DO_IT(MY_ARRAY); long y = DO_TOO(MY_ARRAY);
afin qu'au moment de la compilation
#define MY_ARRAY { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 \ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
Comment mon DO_IT et DO_TOO doivent ressembler à cela pour que cela fonctionne? J'ai vraiment du mal avec celui-ci et je n'arrive pas à trouver une solution qui fonctionne. Toute aide est grandement appréciée.
3 Réponses :
Si vous supprimez {
}
, vous pouvez simplement:
#include <initializer_list> #define MY_ARRAY {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77} constexpr unsigned long long DO_IT(const std::initializer_list<int>& l) { unsigned long long r = 0; for (auto&& i : l) { r >>= 8; r |= (unsigned long long)i << (7 * 8); } return r; } constexpr long a = DO_IT(MY_ARRAY);
mettre à jour:
#define MY_ARRAY2 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF #define REVERSE_LL_8(_0,_1,_2,_3,_4,_5,_6,_7) (\ (unsigned long long)(_7) << (7 * 8) | \ (unsigned long long)(_6) << (6 * 8) | \ etc... \ (unsigned long long)(_0) << (0 * 8)) #define DO_IT_2(_0,_1,_2,_3,_4,_5,_6,_7,...) \ REVERSE_LL_8(_0,_1,_2,_3,_4,_5,_6,_7) #define DO_IT(x) DO_IT_2(x) #define DO_TOO_2(a0,a1,a2,a3,a4,a5,a6,a7,_0,_1,_2,_3,_4,_5,_6,_7) \ REVERSE_LL_8(_0,_1,_2,_3,_4,_5,_6,_7) #define DO_TOO(x) DO_TOO_2(x) DO_IT(MY_ARRAY2) DO_TOO(MY_ARRAY2)
Ok, ouais. En fait, je peux simplement supprimer les accolades et les ajouter via une autre macro pour le code hérité et utiliser essentiellement MY_ARRAY_RAW comme ceci, puis faire en sorte qu'un MY_ARRAY soit un {MY_ARRAY_RAW}. Je vais essayer ça. Merci!
Merci!!! Cela fonctionnait à l'aide de macros. J'ai dû faire quelques changements car j'utilise MSVC et n'adhère pas à la norme lors de l'extension des arguments. J'ai trouvé une solution cependant: stackoverflow.com/questions/35210637 /…
Veuillez jeter un œil à la solution de la bibliothèque Boost: https://www.boost.org/ doc / libs / 1_68_0 / libs / preprocessor / doc / ref / array_reverse.html
BOOST_PP_ARRAY_REVERSE est ce dont vous avez besoin.
Merci pour la suggestion, mais je préfère ne pas ajouter la bibliothèque boost si je peux l'aider.
Il ne semble pas y avoir de raison d'utiliser des macros ici, vous avez juste besoin d'une évaluation au moment de la compilation:
#include <stdio.h> #include <stdint.h> #define MY_INIT_LIST { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, \ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, } #define MY_ARRAY (const uint32_t[]) MY_INIT_LIST int main (void) { for(size_t i=0; i<16; i++) printf("%X ", MY_ARRAY[i]); const uint32_t u32 = MY_ARRAY[3] << 24 | MY_ARRAY[2] << 16 | MY_ARRAY[1] << 8 | MY_ARRAY[0] << 0 ; printf("\n%X\n", u32); }
Ceci est indépendant et standard C. Il peut être facilement réécrit pour être utilisé Types 64 bits qui est probablement (?) Ce que vous voulez réellement?
Votre tableau a-t-il toujours les mêmes éléments numériques? Pouvez-vous modifier votre macro
MY_ARRAY
afin qu'elle n'inclue pas les accolades? Et pourquoi voulez-vous le faire avec une macro et non avec une fonction?Il contient en fait 16 éléments (je mettrai à jour la question). Numéro hexadécimal de 64 bits. Il contient les accolades car il sera nécessaire plus tard dans le code hérité sur lequel je travaille.
#define reverse (a, b) b, a
?DO_IT
est impossible - il est impossible de supprimer{
}
au niveau du préprocesseur. Pouvez-vous supprimer le{
}
? Qu'est-il arrivé également à0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
?Mais cela ne rentrera pas dans un int 64 bits; vous auriez besoin de 128 bits. Si vous pouvez définir
MY_ARRAY
en deux étapes - l'une sans accolades, l'autre avec accolades - vous pouvez alors créer le nombre avec bt-shifting:#define (A0, A1, .. .) (((A0) << 0) | ((A1) << 8) | ...)
C et C ++ sont des langages différents, et C ++ peut effectuer des calculs de compilation plus complexes - non basés sur des macros - que C. Choisissez votre langage.
Ok, c'est plus compliqué que je ne le pensais. C'est en fait un tableau de 16 octets qui doit être stocké dans 2 variables. Dieu aide moi. Nous utilisons un compilateur C ++ pour que je puisse utiliser les fonctionnalités C ++ (bien qu'elles ne soient pas encore utilisées car il s'agit de code C hérité).
La virgule
0x77 \ 0x88
est manquante, par intention ou par faute de frappe?