我对struct
中字节的排序方式感到有些困惑。
我们说我有以下结构:
struct container {
int myint;
short myshort;
long mylong;
};
现在,我想初始化类型为struct container
的变量,就像下面一样,除了我希望使用数组执行它。
struct container container1 = {.myint = 0x12345678,
.myshort = 0xABCD,
.mylong = 0x12345678};
假设sizeof
int
和long
为4
,而short
的{{1}}为2
。
假设没有填充。
那么10 bytes
的{{1}}的布局如何?
这取决于字节顺序吗?
会是这样的:
struct
或者喜欢:
0x12345678 ABCD 12345678
我想要做的是:我有以下的char数组:
0x78563412 CDAB 78563412
我想手动用数据填充此数组,然后char buffer[10] = {0};
到memcpy
。
我应该做 [1] :
struct
或应该是 [2] :
buffer[0] = 0x12345678 & 0xFF;
buffer[1] = 0x12345678 >> 8 & 0xFF;
buffer[2] = 0x12345678 >> 16 & 0xFF;
buffer[3] = 0x12345678 >> 24 & 0xFF;
...
buffer[9] = 0x12345678 >> 24 & 0xFF;
在我做buffer[0] = 0x12345678 >> 24 & 0xFF;
buffer[1] = 0x12345678 >> 16 & 0xFF;
buffer[2] = 0x12345678 >> 8 & 0xFF;
buffer[3] = 0x12345678 & 0xFF;
...
buffer[9] = 0x12345678 & 0xFF;
之前:
memcpy
而且,如果我正在写入数组并复制到memcpy(&container1, buffer, sizeof(container1);
,它是否可以跨系统移植,特别是在字节序方面?
修改: [1] 是否适用于小端机器和 [2] 的大端?
答案 0 :(得分:2)
这取决于字节顺序吗?
是的,取决于机器的字节顺序。因此,您的逻辑将根据机器的字节顺序而改变。
由于结构填充,没有可移植方式* 来执行此操作。虽然不同的编译器确实提供了自定义方法来禁用struct padding。检查Force C++ struct to not be byte aligned。
您可以添加static_assert
(需要C11支持),以确保您的代码不会编译,除非您的结构紧凑。您不会拥有可移植代码,但您仍然可以确定,如果您的代码编译,它将表现正常。
static_assert(sizeof(container) == sizeof(int) + sizeof(short) + sizeof(long));
答案 1 :(得分:1)
还有一个问题,即结构中元素对齐的问题。
您的结构具有间隙以进行对齐。真实的布局就像你做的那样:
struct container {
int myint;
short myshort;
char __pad__[2]; // padding to align mylong to 4/8 byte boundary
long mylong;
};
使用union
:
union {
struct container vals;
char buf[10];
};
但是,为什么你想这样做?对于我能想到的几乎任何场景,可能有一种更清晰的方法来获得效果。
当你说 array 时,你的意思是你想要初始化你的结构数组吗?这可以做到:
struct container conts[3] = {
{ .myint = 1, .myshort = 2, .mylong = 3 },
{ .myint = 4, .myshort = 5, .mylong = 6 },
{ .myint = 7, .myshort = 8, .mylong = 9 }
};
BTW,是在C中做static_assert
的方法:
// compile time assertion -- if the assertion fails, we will get two case 0:'s
// which will cause the compiler to flag this
#define static_assert(_assert) \
do { \
switch (0) { \
case (_assert): \
break;
case 0: \
break; \
} \
} while (0)