寻找 C/C++ 预处理器宏或模板来反转十六进制宏数组并生成十六进制数
Looking for C/C++ pre-processor macro or template to reverse a hex macro array and generate hex number
我有一个非常具体的问题。我有以下宏定义,稍后将在代码中使用。
#define MY_ARRAY { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 \
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
现在我想在编译期间反转顺序并生成一个值以在编译期间直接嵌入到可执行文件中。所以基本上,我想要以下代码
long x = DO_IT(MY_ARRAY);
long y = DO_TOO(MY_ARRAY);
以便在编译时
x = 0x7766554433221100;
y = 0xFFEEDDCCBBAA9988;
我的 DO_IT 和 DO_TOO 必须看起来像什么才能起作用?我真的在为这个问题苦苦挣扎,似乎找不到可行的解决方案。非常感谢任何帮助。
如果删除 {
}
,您可以:
#define MY_ARRAY 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
#define DO_IT_2(_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(x) DO_IT_2(x)
更新:
#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)
so I can use C++ features
在 C++ 中,它是一个非常简单的 contexpr
函数 initializer_list
:
#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);
请看一下 Boost 库的解决方案:
https://www.boost.org/doc/libs/1_68_0/libs/preprocessor/doc/ref/array_reverse.html
BOOST_PP_ARRAY_REVERSE就是你所需要的。
似乎没有任何理由在这里使用宏,你只需要编译时评估:
#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);
}
这是独立于字节序的标准 C。它可以很容易地重写为使用 64 位类型,这可能是(?)您真正想要的?
我有一个非常具体的问题。我有以下宏定义,稍后将在代码中使用。
#define MY_ARRAY { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 \
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
现在我想在编译期间反转顺序并生成一个值以在编译期间直接嵌入到可执行文件中。所以基本上,我想要以下代码
long x = DO_IT(MY_ARRAY);
long y = DO_TOO(MY_ARRAY);
以便在编译时
x = 0x7766554433221100;
y = 0xFFEEDDCCBBAA9988;
我的 DO_IT 和 DO_TOO 必须看起来像什么才能起作用?我真的在为这个问题苦苦挣扎,似乎找不到可行的解决方案。非常感谢任何帮助。
如果删除 {
}
,您可以:
#define MY_ARRAY 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
#define DO_IT_2(_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(x) DO_IT_2(x)
更新:
#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)
so I can use C++ features
在 C++ 中,它是一个非常简单的 contexpr
函数 initializer_list
:
#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);
请看一下 Boost 库的解决方案: https://www.boost.org/doc/libs/1_68_0/libs/preprocessor/doc/ref/array_reverse.html
BOOST_PP_ARRAY_REVERSE就是你所需要的。
似乎没有任何理由在这里使用宏,你只需要编译时评估:
#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);
}
这是独立于字节序的标准 C。它可以很容易地重写为使用 64 位类型,这可能是(?)您真正想要的?