首页 > 解决方案 > 在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标准不提供结构转换,也没有通过问题中显示的指针转换定义重新解释。(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出于某种安全考虑,但您还必须确保结构布局与您的目的兼容。


推荐阅读