我们的团队目前正在将一些旧架构的代码移植到基于 ARM Cortex M3 平台的新产品中,该平台使用定制版本的 GCC 4.5.1。我们正在从通信链路读取数据,并尝试将原始字节数组转换为结构以干净地解析数据。在将指针转换为结构并取消引用后,我们收到警告:“取消引用类型双关指针将破坏严格别名规则”。
经过一番研究,我意识到由于 char 数组没有对齐规则并且结构必须是字对齐的,因此转换指针会导致未定义的行为(坏事)。我想知道是否有更好的方法来做我们正在尝试的事情。
我知道我们可以使用 GCC 的“属性((aligned (4)))”明确地对字符数组进行字对齐。我相信这将使我们的代码“更安全”,但警告仍然会使我们的构建变得混乱,并且我不想禁用警告以防这种情况再次出现。我们想要的是一种安全地做我们正在尝试的事情的方法,如果我们稍后在另一个地方尝试做一些不安全的事情,它仍然会通知我们。由于这是一个嵌入式系统,RAM 的使用和闪存的使用在某种程度上很重要。
可移植性(编译器和架构)不是一个大问题,这仅适用于一种产品。但是,如果存在便携式解决方案,那将是首选。
这是我们当前正在做的一个(非常简化的)示例:
#define MESSAGE_TYPE_A 0
#define MESSAGE_TYPE_B 1
typedef struct MessageA __attribute__((__packed__))
{
unsigned char messageType;
unsigned short data1;
unsigned int data2;
}
typedef struct MessageB __attribute__((__packed__))
{
unsigned char messageType;
unsigned char data3;
unsigned char data4;
}
// This gets filled by the comm system, assume from a UART interrupt or similar
unsigned char data[100];
// Assume this gets called once we receive a full message
void ProcessMessage()
{
MessageA* messageA;
unsigned char messageType = data[0];
if (messageType == MESSAGE_TYPE_A)
{
// Cast data to struct and attempt to read
messageA = (MessageA*)data; // Not safe since data may not be word aligned
// This may cause undefined behavior
if (messageA->data1 == 4) // warning would be here, when we use the data at the pointer
{
// Perform some action...
}
}
// ...
// process different types of messages
}