将一个结构变量分配给另一个具有位字段的相同类型的结构变量,在 C、UB 中?

问题描述 投票:0回答:1

我问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。如果内存不足,是否整个 位域可以读取,该值应作为无符号整数读取 并且整个位域的值变成不确定值。

在以下情况下,行为未定义:

**当左值访问存储时,该左值未指定与有效类型兼容的结构或联合类型的对象 左值。

当将值存储到对象的位字段或从对象的位字段读取值时 与组件的分配顺序不同的顺序 具有整数类型的值。**

c c99
1个回答
0
投票

将结构分配给兼容结构已明确定义。它是否有位字段并不重要。引用自 C99 草案 N1256:

6.5.16.1 简单赋值

限制

  1. 应满足以下条件之一:96)

    • 左操作数具有限定或不限定算术类型,右操作数具有算术类型;
    • 左操作数具有限定或非限定版本的结构或联合类型与右操作数兼容;

C99 §6.7.2.1.14 与结构无关。这是关于工会的:

工会的规模足以容纳其最大的成员。的值在 大多数成员可以随时存储在联合对象中。一个指向a的指针 联合对象,经过适当转换,指向它的每个成员(或者如果一个成员是位- 字段,然后到它所在的单位),反之亦然。

你引用的文字也完全是胡说八道。例如:

当值存储在结构体或联合类型对象的位字段中时, 该值应使用整数类型和 ANSI/IEEE Std 754-1985 定义的编码来表示。

IEEE-1985是浮点标准,与整数无关。

© www.soinside.com 2019 - 2024. All rights reserved.