gpt4 book ai didi

c - 是否从 C 标准定义的同一 union 中的不同成员分配给 union 成员?

转载 作者:行者123 更新时间:2023-12-03 14:37:25 25 4
gpt4 key购买 nike

考虑:

union { int i; char c; } x = {0};
x.c = x.i;
C 2018 6.15.16.1 3,关于简单赋值,说:

If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have qualified or unqualified versions of a compatible type; otherwise, the behavior is undefined.

x.cx.i重叠但不完全重叠并且没有兼容类型的版本。那么这个赋值的行为不是由 C 标准定义的吗?

最佳答案

在我看来,您发现了标准中的缺陷。我认为意图是x.c = x.i;具有未定义的行为,但该段落(自 C90 以来一直在标准中)没有正确表达该意图。
该措辞适用于简单分配。在一个简单的赋值中,LHS 必须是一个左值,而 RHS 只是一个表达式。如果 RHS 恰好是一个左值,它会按照 6.3.2.1p2 中的描述进行左值转换。左值转换后就不再是左值了。
可以合理地说,当对象重叠时,将一个对象复制到另一个对象的赋值具有未定义的行为(除非重叠是精确的并且对象具有兼容的类型)。但是赋值不对两个对象进行操作;它对一个对象(LHS)和一个非左值表达式(RHS)进行操作。
该段落说该值“是从另一个对象读取的”。这是模棱两可的。对象的名称必须是整个 RHS 表达式,还是可以只是一个子表达式?如果是后者,则 x.c = x.i + 1;会有未定义的行为,在我看来这是荒谬的。
正如所写,引用段落中给出的条件不可能发生。
如果要更正该段落,则应仅在 RHS 是左值时(在左值转换之前)才适用,并讨论 LHS 指定的对象与 RHS 指定的对象之间的重叠。
这里的特定情况,分配重叠的小整数对象,在实践中不太可能引起问题,但我们可以构建更成问题的情况。例如:

int main() {
struct big {
int array[1000];
};

struct big_wrapper {
int n;
struct big b;
};


union u {
struct big x;
struct big_wrapper y;
};

union u obj;
obj.x = obj.y.b;
}
这里的赋值将一个大对象的值复制到另一个大对象中,其中两个对象重叠但不在同一位置开始。为了正确实现这一点,编译器必须检测重叠并可能生成对 memmove() 的调用。或等效的。如果通过指针执行分配,则重叠可能不会直接可见。使行为未定义允许编译器为非重叠情况生成有效的代码。
我相信,意图是这个赋值也有未定义的行为,但左值转换再次意味着该意图没有明确表达。
在我看来,应该更新该段落以说明当 RHS 是左值时它适用,并且相关对象是 LHS 和转换前的 RHS。

关于c - 是否从 C 标准定义的同一 union 中的不同成员分配给 union 成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65077630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com