Why is casting from char to std::byte potentially undefined behavior?

前端 未结 1 800
死守一世寂寞
死守一世寂寞 2021-02-05 05:08

The std::byte of C++17 is required to be enum class:

enum class byte : unsigned char {};

We may want to use that std::byte

1条回答
  •  囚心锁ツ
    2021-02-05 05:18

    This is going to be fixed in the 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 the rationale behind the change from (C++11) unspecified to (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.

    And here's the rationale behind the C++2a fix:

    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.

    0 讨论(0)
提交回复
热议问题