mastodon.cardina1.red は、数々の独立したMastodonサーバーのうちのひとつです。サーバーに登録してFediverseのコミュニティに加わってみませんか。

サーバーの情報

3
人のアクティブユーザー

gccとclangで挙動が違うC++コード。多分UBを踏んでいるが、どこで踏んでいるかはいまいちよくわかっていない。

@anqou C++20 (n4868) §7.6.1.9/10
timsong-cpp.github.io/cppwp/n4

> 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.

ここに該当して未定義動作ですね

timsong-cpp.github.io[expr.static.cast]

std::byte - cppreference.com
en.cppreference.com/w/cpp/type

さっきのやつ <mstdn.anqou.net/@anqou/1071909>、構図としては std::byte とほぼ同じなので、 -1 を bool に変化した true にならないとおかしい気がするんだよな……

en.cppreference.comstd::byte - cppreference.com

timsong-cpp.github.io/cppwp/n4
[dcl.enum]/8:
> For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type.

> The resulting value is the same as converting the original value to the underlying type of the enumeration ([conv.fpint]), and subsequently to the enumeration type.

timsong-cpp.github.io/cppwp/n4
[expr.static.cast]/10:
> 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.

timsong-cpp.github.io/cppwp/n4
[conv.bool]/1:
> A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a prvalue of type bool.
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.

だよなぁ……

timsong-cpp.github.io[dcl.enum]

timsong-cpp.github.io/cppwp/n4
[dcl.init.list]/3.8:
> Otherwise, if T is an enumeration with a fixed underlying type ([dcl.enum]) U, the initializer-list has a single element v, v can be implicitly converted to U, and the initialization is direct-list-initialization, the object is initialized with the value T(v) ([expr.type.conv]); if a narrowing conversion is required to convert v to U, the program is ill-formed.

timsong-cpp.github.io[dcl.init.list]

これは braced initializer の話で、実際 Bit{-2} したら ill-formed なのでエラーになる:

wandbox.org/permlink/FJcw7RxBB

timsong-cpp.github.io/cppwp/n4
[basic.fundamental]/10:
> Type bool is a distinct type that has the same object representation, value representation, and alignment requirements as an implementation-defined unsigned integer type.
The values of type bool are true and false.

これもしかして関係あるのでは

timsong-cpp.github.io[basic.fundamental]
らりお・ザ・何らかの🈗然㊌ソムリエ

timsong-cpp.github.io/cppwp/n4
[expr.type.conv]/2:
> If the initializer is a parenthesized single expression, the type conversion expression is equivalent to the corresponding cast expression.

timsong-cpp.github.io[expr.type.conv]

timsong-cpp.github.io/cppwp/n4
[expr.cast]/4
> If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed.

で、 Bit(-2) は、 [expr.cast]/4.1 の const_cast ([expr.const.cast], §7.6.1.11) が該当しないから [expr.cast]/4.2 の static_cast として扱われることになるはず

timsong-cpp.github.io[expr.cast]

mastodon.cardina1.red/@lo48576

この最後の "The resulting value is ..." という文は直前の "floating-point type can be also ..." にかかっていて整数から enum への場合には関係ないと考えるべきだな

mstdn.anqou.net/@anqou/1071909

まだこれのことを考えているのですが、規格追いまくってるけど implementation-defined なやつかコンパイラのバグか確定しきれずにいます (少なくとも UB ではなさそう)

mstdn.anqou.net艮 鮟鱇 (@anqou@mstdn.anqou.net)艮 鮟鱇