c - 在C中将结构实例转换为另一种类型的正确方法是什么
问题描述
在这里对 C++ 提出了一个类似的问题: What is the proper way of cast objects to unrelated objects in C++
#include <stdio.h>
typedef struct s1{
} s1;
typedef struct s2{
} s2;
int main(){
s1 a;
s2 b;
b = *(s2*)&a;
return 0;
}
使用 bit cast 是实现此目的的唯一方法吗?
解决方案
C标准不提供结构转换,也没有通过问题中显示的指针转换定义重新解释。(C 2018 6.5 7 中指定的类型组合支持某些此类重新解释,但不支持独立结构。)该标准提供了另外两种将对象重新解释为另一种类型的方法。
首先,可以简单地将一个对象的字节复制到另一个对象中:
_Static_assert(sizeof a == sizeof b, "a and b must be the same size.");
memcpy(&b, &a, sizeof b);
对于小对象,启用优化的良好编译器可能会直接从内存或寄存器中删除副本并解释新类型中的数据。
其次,可以存储给一个工会成员并通读另一个(C 2018 6.5.2.3 3,见脚注 99):
_Static_assert(sizeof a == sizeof b, "a and b must be the same size.");
b = (union { struct s1 s1; struct s2 s2; }) {a} .s2;
括号中的联合类型以复合文字开头。{a}
给出a
作为联合的初始值,特别是对于成员s1
。然后.s2
访问s2
成员。
请注意,虽然_Static_assert
出于某种安全考虑,但您还必须确保结构布局与您的目的兼容。
推荐阅读
- java - 等待更改直到执行完成并等待下一次执行直到更改完成
- c# - 如何使用 C# 删除带有 EventRecordID 的事件日志源
- paypal - PayPal 自定义窗口弹出
- c# - 使用 .sys 驱动程序 c# 读取受保护的程序内存
- docusignapi - DocuSign API - 授权码授予流程刷新问题
- javascript - ant 设计进度条。使用台阶可防止全宽
- javascript - 如何在html页面上显示从函数返回的数组项
- c - realloc 后无限循环
- python - 覆盖 simple-jwt 的 TokenObtainPairSerializer 来实现 2FA
- ssis - 参数化 ssis 连接管理器(带有单个包的项目)有什么用?