ARM GCC未对齐访问

时间:2013-09-17 09:34:00

标签: gcc packed

如果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;
}

1 个答案:

答案 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时,它应该处理任何未对齐的访问和位/字节操作。