gpt4 book ai didi

c++ - 为什么从 char 转换为 std::byte 可能是未定义的行为?

转载 作者:IT老高 更新时间:2023-10-28 21:48:10 27 4
gpt4 key购买 nike

std::byte C++17的必须是枚举类:

enum class byte : unsigned char {};

我们可能想要使用 std::byte表示原始内存而不是 char 之一s 因为它的类型更安全,定义了特定于字节的运算符并且不能提升到 int出乎意料的喜欢 char是的。我们需要使用显式转换或 to_integer转换 std::byte到其他整数。然而,我们仍然从很多来源得到 char (或更可能是 char 的整个缓冲区),因此可能想要转换它:

void fn(char c)
{
std::byte b = static_cast<std::byte>(c);
// ... that may invoke undefined behavior, read below
}

char 的签名是实现定义的,所以 std::numeric_limits<char>::is_signed可能是 true .因此以上c可能有超出 unsigned char 范围的负值.

现在在 8.2.9 中的 C++17 标准中静态转换 [expr.static.cast] 第 10 段我们可以读到:

A value of integral or enumeration type can be explicitly converted to a complete enumeration type. The value is unchanged if the original value is within the range of the enumeration values (10.2). Otherwise, the behavior is undefined.

从10.2我们可以看出,提到的范围是底层类型的范围。因此,为了避免未定义的行为,我们必须编写更多代码。例如,我们可以向 unsigned char 添加一个类型转换。在强制转换期间实现模运算的定义效果:

void fn(char c)
{
std::byte b = static_cast<std::byte>(static_cast<unsigned char>(c));
// ... now we have done it in portable manner?
}

我是不是误会了什么?这不是过于复杂和限制性的吗?为什么 enum class 不能具有无符号基础类型的基础类型是否像其基础类型一样遵循模算术?请注意,无论如何,编译器很可能将整行强制转换编译为空。 char自 C++14 以来,当它被签名时必须是二进制补码,因此它的按位表示必须与模算术转换为 unsigned char 之后的相同。 .谁从这种正式的未定义行为中受益以及如何受益?

最佳答案

这将在 next standard 中修复:

A value of integral or enumeration type can be explicitly converted to a complete enumeration type. If the enumeration type has a fixed underlying type, the value is first converted to that type by integral conversion, if necessary, and then to the enumeration type. If the enumeration type does not have a fixed underlying type, the value is unchanged if the original value is within the range of the enumeration values ([dcl.enum]), and otherwise, the behavior is undefined

Here's从 (C++11) unspecified 更改为 (C++17) undefined 背后的基本原理:

Although issue 1094 clarified that the value of an expression of enumeration type might not be within the range of the values of the enumeration after a conversion to the enumeration type (see 8.2.9 [expr.static.cast] paragraph 10), the result is simply an unspecified value. This should probably be strengthened to produce undefined behavior, in light of the fact that undefined behavior makes an expression non-constant.

还有 here's C++2a 修复背后的基本原理:

The specifications of std::byte (21.2.5 [support.types.byteops]) and bitmask (20.4.2.1.4 [bitmask.types]) have revealed a problem with the integral conversion rules, according to which both those specifications have, in the general case, undefined behavior. The problem is that a conversion to an enumeration type has undefined behavior unless the value to be converted is in the range of the enumeration.

For enumerations with an unsigned fixed underlying type, this requirement is overly restrictive, since converting a large value to an unsigned integer type is well-defined.

关于c++ - 为什么从 char 转换为 std::byte 可能是未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52554069/

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