- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们的团队目前正在使用 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/
在我的 java 代码中,我做了类似的事情: int sleep = 0; sleep(sleep); sleep++; 被bos指出不好。它不能在 php 中正常工作。 在 java 中使用上述代码
我有一个程序使用第 3 方库进行一些计算,我在与主应用程序不同的线程上启动该程序。不幸的是,此计算可能需要很长时间,并且不提供进度更新和取消的接口(interface)。 为了拥有这样的界面,我想创建
C++ 是否有任何等效于 python 的函数 os.path.join?基本上,我正在寻找将文件路径的两个(或多个)部分组合在一起的东西,这样您就不必担心确保这两个部分完美地结合在一起。如果它在 Q
我正试图站起来(非商业)web application使用 neo4j Community 3.5.2 作为后端。 应用程序以两种方式与图形交互: 服务器端(安全的)用 flask 编写新的节点和关系
我正在开发一个将有许多外部用户的在线应用程序。至于现在,我的连接方法是为所有用户托管一个中央数据库,而他们从自己的服务器文件连接。 方法: PHP 连接文件(托管在他们的服务器上;文件由我提供) >>
我创建了一个将所有事件通知代码转换为字符串的函数。真的很简单。 我有一堆常量,比如 const _bstr_t DIRECTSHOW_MSG_EC_ACTIVATE("A video window i
我想将(附加)信息从过滤器传递到资源。我目前尝试这样做的方式是,在 Filter 中: getContext().getAttributes().put("additionalInformation"
我想计算转换系数。为此,我必须除以例如的最大值。 ushort 为 uchar 的最大值。 我想通过将参数传递给函数或类型名来动态地执行此操作。然后我想选择最大值并执行计算。 有两个问题: 如何动态选
我希望我的用户在用 Java 请求列表时能够编写自己的过滤器。 选项 1) 我正在考虑将 JavaScript 与 Rhino 结合使用。 我将用户的过滤器作为 javascript 字符串获取。然后
(安全地)提供来自不同域的图像是否符合 PCI 标准?我搜索了 PCI DSS 2.0 PDF,但没有找到任何引用资料。 最佳答案 图像不符合 PCI 合规性。 PCI DSS covers the
我们正在将 spring 和 hibernate 用于 web 应用程序:该应用程序有一个购物车,用户可以在其中放置商品。为了保存不同登录名之间要查看的项目,购物车中的项目值存储在表中。提交购物车时,
我正在为多个客户创建一个具有电子商务元素的 Rails 应用程序 - 我希望这些客户能够在管理区域中指定计算运费的公式;因为方法可能不同。 让我们假装一下,我允许他们输入 ruby 代码,然后我稍
我正在 Eclipse 中开发一个 Java 项目,使用 Maven 构建和管理依赖项。该项目分布在 5 个 Eclipse 项目中,其中一个是父 POM。我正在研究基于另一个团队实现的更复杂服务器的
我想在 ADO.NET 数据服务中存储每线程数据。在线程特定的静态变量上使用 ThreadStatic 属性是否安全,或者我会遇到问题吗?我担心的是,我的 ThreadStatic 变量在请求完成并且
Stackoverflow 上至少有一篇与此主题相关的帖子:Generate password in python 你会发现这个主题甚至在 PEP 中也受到了一些批评。这里提到:https://www
对于我工作中的一个项目,我需要创建一个独立的 Python 安装(来自源代码)。然而,完整的目录占用大约 90MB 的磁盘空间,虽然不多,但太多了,无法一遍又一遍地复制。 我可以从自定义 python
例如,我有一张学生表,我有一本 Python 字典 mydict = {"fname" : "samwise", "lname" : "gamgee", "age" : 13} 我怎样才能安全地生成一
我经常在代码中遇到使用 memset 手动零初始化的 POD 结构,如下所示: struct foo; memset(&foo, 0, sizeof(foo)); 我检查了 C++11 标准,它说:“
我是一名优秀的程序员,十分优秀!