gpt4 book ai didi

c - 如何在嵌入式系统中安全地执行类型双关

转载 作者:太空狗 更新时间:2023-10-29 17:16:59 24 4
gpt4 key购买 nike

我们的团队目前正在使用 GCC 4.5.1 的自定义版本,将旧架构的一些移植代码用于基于 ARM Cortex M3 平台的新产品。我们正在从通信链路读取数据,并尝试将原始字节数组转换为结构以清晰地解析数据。将指针转换为结构并取消引用后,我们收到警告:“取消引用类型双关指针将违反严格的别名规则”。

经过一些研究后,我意识到由于 char 数组没有对齐规则并且结构必须按字对齐,所以强制转换指针会导致未定义的行为(坏事)。我想知道是否有更好的方法来完成我们正在尝试的事情。

我知道我们可以使用 GCC 的“attribute ((aligned (4)))”显式地字对齐 char 数组。我相信这将使我们的代码“更安全”,但警告仍然会使我们的构建变得困惑,我不想禁用警告以防再次出现这种情况。我们想要的是一种安全地做我们正在尝试的事情的方法,如果我们稍后试图在另一个地方做一些不安全的事情,它仍然会通知我们。由于这是一个嵌入式系统,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
}

最佳答案

正如已经指出的那样,转换指针是一种狡猾的做法。

解决方案:使用 union

struct message {
unsigned char messageType;
union {
struct {
int data1;
short data2;
} A;
struct {
char data1[5];
int data2;
} B;
} data;
};

void func (...) {
struct message msg;
getMessage (&msg);

switch (msg.messageType) {
case TYPEA:
doStuff (msg.data.A.data1);
break;
case TYPEB:
doOtherStuff (msg.data.B.data1);
break;
}
}

通过这种方式,编译器知道您正在通过不同的方式访问相同的数据,并且警告和 Bad Things 将消失。

当然,您需要确保结构对齐和打包与您的消息格式相匹配。当心字节序问题,例如链接另一端的机器不匹配。

关于c - 如何在嵌入式系统中安全地执行类型双关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9011884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com