C11中通过共用体通用结构体访问共享字段的合规性及类型疑问
关于C11标记联合与公共初始序列的问题解答
问题1:CurrentId_t、VoltageId_t与int是否属于兼容类型?
不属于。根据C11标准,枚举类型是独立的类型——即便它的底层存储通常采用int(编译器可选择合适的整数类型),但枚举类型本身和int并不属于兼容类型。CurrentId_t和VoltageId_t都是typedef定义的枚举类型别名,本质仍为枚举类型,因此和int类型不兼容。
问题2:对C11 §6.5.2.3条款的理解是否正确?
你的核心理解方向没错,但当前代码的用法不符合该条款的要求。
C11 §6.5.2.3第6款明确规定:当共用体包含多个结构体类型成员时,如果这些结构体拥有公共初始序列(即开头连续的成员列表完全一致),且初始序列中对应位置的成员类型兼容,那么当其中一个结构体成员被写入后,可以安全读取另一个结构体成员的公共初始序列部分。
但你的代码中,CommonData_t的id是int,而CurrentData_t、VoltageData_t的id是枚举类型(和int不兼容),这导致三个结构体的公共初始序列第一个成员类型不匹配,不符合标准中“类型兼容”的要求。因此你想通过common.value直接读取current.value或voltage.value的做法,属于未定义行为,标准不保证其正确性。
如果想实现无需switch直接读取共享的value字段,更可靠的方式是把value单独放到标记结构体的顶层,示例如下:
typedef struct { enum { CURRENT, VOLTAGE } kind; float value; // 共享字段直接放在顶层 union { CurrentId_t current_id; VoltageId_t voltage_id; }; } Measurement_t;
这样无论哪种类型,都可以直接访问value,同时通过kind判断后访问对应的id字段,完全符合标准要求。
内容的提问来源于stack exchange,提问作者gberth
相关产品推荐
相关产品推荐

