对齐与已打包属性

时间:2011-08-11 12:37:27

标签: c attributes embedded structure memory-alignment

我正在研究16位PIC的固件并用C语言编写(Microchip C30编译器)。我的设备从外部设备接收一长串字节,然后我试图将这些字节复制到一个结构中。结构定义如下:

typedef struct __attribute__((__packed__)) {
    char    F1Nickname[17];
    char    F2Nickname[17];
    DWORD   F1CurrentPos;
    DWORD   F2CurrentPos;
    WORD    F1CurrentTemp;
    WORD    F2CurrentTemp;
    DWORD   F1MaxPos;
    DWORD   F2MaxPos;
    BYTE    F1TempCompOn;
    BYTE    F2TempCompOn;
    BYTE    CheckSum;
} deviceStatus;

我遇到一个奇怪的问题,即每当结构中的总字节数为奇数时,我的程序就会冻结并被AddressError服务例程捕获。我可以通过简单地向结构添加一个额外的字节来解决这个问题,但这似乎是一个创可贴修复。

我将packed属性放在结构上,因为我想确保编译器没有在我的变量之间插入任何填充字节。如果发生这种情况,从接收到的字符数组复制时,我的结构中的值将不正确。

我知道还有一个名为aligned的属性。对齐只是将结构的开头与偶数字节对齐,还是将结构中的每个项目与偶数字节对齐?你认为这里需要对齐的属性吗?如果我将aligned属性添加到此结构,我还应该将它添加到发送数据的设备上的结构,对吧?截至目前,它们的定义与上面显示的完全相同。

如果我添加了aligned属性,我应该删除packed属性吗?他们基本上没有相反的做法吗?

2 个答案:

答案 0 :(得分:2)

__attribute____packed__不是C标准的一部分,是编译器提供的扩展。唯一能够确定它们意味着什么的方法是在编译器文档中查找它。

答案 1 :(得分:2)

某些微处理器体系结构只能对与字边界对齐的地址进行数据提取,并且如果它们不是字对齐则会抛出异常。编译器通常会帮助并生成执行必要杂技的代码,以确保提取字是对齐的,但编译器似乎不是这种情况,这就是您看到异常的原因。

在您的情况下,您使用struct来序列化数据,因此必须打包。在这种情况下,您必须重新排列struct以确保不跨字边界读取,或者您需要使用和解压缩结构并手动序列化数据。