我问AI(克劳德),它告诉我是UB。这是真的吗?
#include <stdio.h>
struct BitFieldStruct {
unsigned int a : 5;
unsigned int : 3; // 3位填充位
unsigned int b : 6;
unsigned int c : 10;
};
int main() {
struct BitFieldStruct s1 = {10, 20, 300};
struct BitFieldStruct s2;
printf("s1.a = %d, s1.b = %d, s1.c = %d\n", s1.a, s1.b, s1.c);
s2 = s1; // UB
printf("s2.a = %d, s2.b = %d, s2.c = %d\n", s2.a, s2.b, s2.c);
// may not same as s1
return 0;
}
上网查了一下还是一头雾水。
Claude告诉我这是根据C99(6.7.2.1.14)的。我认为克劳德读错了。但英语不是我的母语。我不确定我读得是否正确。
当一个值存储在结构体或联合类型的对象中时, 包括作为联合类型值的一部分的情况, 对象表示应按顺序写入 成员以递增的位域顺序给出,其中 重叠情况下实现定义的行为。命令 对于字节组件是实现定义的。会员的价值观 即根据并集定义存储并集。
当一个值存储在结构体或对象的位字段中时 union 类型,该值应使用整数类型表示,并且 ANSI/IEEE Std 754-1985 定义的编码。该值应为 存储在表示值所需的最少位数中,并且 该值的整数部分(如有)应占据最少的 有效位位置。
当读取位域中的值时,应表示其值 具有整数类型和 ANSI/IEEE Std 定义的编码 754-1985。如果内存不足,是否整个 位域可以读取,该值应作为无符号整数读取 并且整个位域的值变成不确定值。
在以下情况下,行为未定义:
**当左值访问存储时,该左值未指定与有效类型兼容的结构或联合类型的对象 左值。
当将值存储到对象的位字段或从对象的位字段读取值时 与组件的分配顺序不同的顺序 具有整数类型的值。**
将结构分配给兼容结构已明确定义。它是否有位字段并不重要。引用自 C99 草案 N1256:
6.5.16.1 简单赋值
限制
应满足以下条件之一:96)
- 左操作数具有限定或不限定算术类型,右操作数具有算术类型;
- 左操作数具有限定或非限定版本的结构或联合类型与右操作数兼容;
C99 §6.7.2.1.14 与结构无关。这是关于工会的:
工会的规模足以容纳其最大的成员。的值在 大多数成员可以随时存储在联合对象中。一个指向a的指针 联合对象,经过适当转换,指向它的每个成员(或者如果一个成员是位- 字段,然后到它所在的单位),反之亦然。
你引用的文字也完全是胡说八道。例如:
当值存储在结构体或联合类型对象的位字段中时, 该值应使用整数类型和 ANSI/IEEE Std 754-1985 定义的编码来表示。
IEEE-1985是浮点标准,与整数无关。