gpt4 book ai didi

c++ - 这种使用 union 的类型别名会调用未定义的行为吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:39:15 25 4
gpt4 key购买 nike

例如,

#include <cstdint>
#include <cstdio>

struct ipv4addr {
union {
std::uint32_t value;
std::uint8_t parts[4];
};
};

int main() {
ipv4addr addr;
addr.value = static_cast<std::uint32_t>(-1);
std::printf("%hhu.%hhu.%hhu.%hhu",
addr.parts[0], addr.parts[1], addr.parts[2], addr.parts[3]);
}

根据 cppref ,

The details of that allocation are implementation-defined, and it's undefined behavior to read from the member of the union that wasn't most recently written.

看起来代码调用了未定义的行为。但是页面上还说

If two union members are standard-layout types, it's well-defined to examine their common subsequence on any compiler.

这个我不是很明白。它是否使代码行为定义明确?

另请注意 cppref 在 type aliasing 上的描述.

Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:

  • [...]
  • AliasedType is std::byte, char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.

我想这也适用于 std::uint8_t。没有?

最佳答案

公共(public)初始子序列有一个荒谬的具体定义。 intstruct foo{int x;} 有一个共同的初始子序列。

struct foo{int x;}struct bar{int y;} 确实有一个共同的初始子序列。

通过不相关的类型读取内存与从 union 替代方案中读取内存不同。该文本在那里没有任何作用。

假设您的平台有 unit8_t,您可以执行 (std::unit8_t const*)&addr.value 并将其视为 4 字节数组。您获得的字节值是实现定义的。

但是,根据标准,您不能从 parts[i] 中读取(当值存在时)。

编译器可以在标准声明未定义时自由指定行为,但在编译时 constexpr 评估期间除外。

关于c++ - 这种使用 union 的类型别名会调用未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55113934/

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