Title
Unclear semantics of enum class bitmask types
Status
open
Section
[bitmask.types]
Submitter
Geoffrey Romer

Created on 2018-03-26.00:00:00 last changed 64 months ago

Messages

Date: 2019-07-22.17:12:46

Proposed resolution:

This wording is relative to N4727.

  1. Edit [bitmask.types] as indicated:

    -2- The bitmask type bitmask can be written:

    // For exposition only.
    // int_type is an integral type capable of representing all values of the bitmask type.
    enumE bitmask : int_type {
      V0 = 1 << 0, V1 = 1 << 1, V2 = 1 << 2, V3 = 1 << 3, .....
    };
    […]
    

    -3- Here, E may represent either enum or enum class (the choice is implementation-defined unless otherwise specified), and the names C0, C1, etc. represent bitmask elements for this particular bitmask type. The zero value bitmask{} is used to represent an empty bitmask, in which no bitmask elements are set. All suchbitmask elements have distinct, nonzero values such that, for any pair Ci and Cj where ij, Ci & Ci is nonzero and Ci & Cj is zero. Additionally, the value 0 is used to represent an empty bitmask, in which no bitmask elements are set.

Date: 2019-07-22.17:12:46

[ 2019 Cologne Wednesday night ]

Changing existing enums to class enums is an ABI break on some platforms; current wording does not require the use of enums. See N3110.

Daniel to provide requirements tables, Jonathan to assist. Reduce priority to 3

Date: 2018-08-23.00:00:00

[ 2018-08-23 Batavia Issues processing ]

N3110 also touches on this.

Nico to survey the enums in the library and report back on which ones should be class.

Date: 2018-04-23.00:00:00

[ 2018-04-23 Priority set to 2 after discussion on the reflector. ]

Date: 2018-03-26.00:00:00

[bitmask.types] specifies the semantics of a bitmask type in terms of an "exposition only" enum definition, together with some constants and overloads. Notably, it is depicted as an unscoped enum, which implies among other things that it is implicitly convertible to int_type. At least some sources treat that as normative (as of this writing, cppreference.com's documentation for BitmaskType says the expression (X & Y) != 0 is guaranteed to be well-formed), and it's hard to argue that they're wrong on the basis of the existing wording.

On the other hand, many standard library types are depicted as scoped enums, but still specified to be "bitmask types". As far as I can tell, it's impossible in library code to make a scoped enum implicitly convertible to its underlying type, and even if you could, what would be the point? Presumably the specification of those types as scoped enums is intended to have some sort of observable consequences.

In addition, some library types (notably in clause 31) are specified to be bitmask types, without indicating whether they are scoped or unscoped. It's not clear what the standard guarantees about e.g. whether they can be implicitly converted.

I assume the intent is that "bitmask type" doesn't specify an implicit conversion, or any of the other ways unscoped and scoped enums differ, but the standard doesn't actually say that. We really ought to rewrite [bitmask.types] as a requirements table, but here's a quick hack to the existing wording as a stopgap.

History
Date User Action Args
2019-07-22 17:12:46adminsetmessages: + msg10488
2018-08-24 13:31:33adminsetmessages: + msg10131
2018-08-24 13:31:33adminsetstatus: new -> open
2018-05-06 19:10:37adminsetmessages: + msg9844
2018-03-31 11:51:57adminsetmessages: + msg9790
2018-03-26 00:00:00admincreate