如果TStruct被打包,则此代码以Str.D == 0x00223344(不是0x11223344)结束。为什么? ARM GCC 4.7
#include <string.h>
typedef struct {
unsigned char B;
unsigned int D;
} __attribute__ ((packed)) TStruct;
volatile TStruct Str;
int main( void) {
memset((void *)&Str, 0, sizeof(Str));
Str.D = 0x11223344;
if(Str.D != 0x11223344) {
return 1;
}
return 0;
}
答案 0 :(得分:-1)
我猜你的问题与未对齐访问无关,但与结构定义无关。 int
不一定是32位长。根据C标准,int至少为16位长,char至少为8位长。
我的猜测是,你的编译器优化了TStruct,所以它看起来像这样:
struct {
unsigned char B : 8;
unsigned int D : 24;
} ...;
当您将0x11223344
分配给Str.D
时,根据C标准,编译器必须只确保将至少16位(0x3344
)写入{{1 }}。您没有指定Str.D
是32位长,只是它至少是16位长。
您的编译器也可以像这样安排结构:
Str.D
struct {
unsigned char B : 16;
unsigned int D : 16;
} ...;
长度至少为8位,B
长度至少为16位,一切正常。
或许,您想要做的是:
D
这样您就可以确保32位值#include <stdint.h>
typedef struct {
uint8_t B;
uint32_t D;
} __attribute__((packed)) TStruct;
正确写入0x11223344
。对__packed结构使用大小约束类型是个好主意
对于结构内部成员的未对齐访问,编译器应该处理它。如果编译器知道结构定义,那么当您访问Str.D
时,它应该处理任何未对齐的访问和位/字节操作。