<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3092: Unclear semantics of enum class bitmask types</title>
<meta property="og:title" content="Issue 3092: Unclear semantics of enum class bitmask types">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3092.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Open">Open</a> status.</em></p>
<h3 id="3092"><a href="lwg-active.html#3092">3092</a>. Unclear semantics of <code>enum class</code> bitmask types</h3>
<p><b>Section:</b> 16.3.3.3.3 <a href="https://wg21.link/bitmask.types">[bitmask.types]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Geoffrey Romer <b>Opened:</b> 2018-03-26 <b>Last modified:</b> 2020-09-06</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#bitmask.types">active issues</a> in [bitmask.types].</p>
<p><b>View all other</b> <a href="lwg-index.html#bitmask.types">issues</a> in [bitmask.types].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
[bitmask.types] specifies the semantics of a bitmask type in terms of an "exposition only" <code>enum</code> 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 <code>int_type</code>. At least some sources treat that as normative (as 
of this writing, <a href="http://cppreference.com/">cppreference.com</a>'s documentation for 
<a href="http://en.cppreference.com/w/cpp/concept/BitmaskType"><code>BitmaskType</code></a> says the expression 
<code>(X &amp; Y) != 0</code> is guaranteed to be well-formed), and it's hard to argue that they're wrong on the basis 
of the existing wording.
<p/>
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.
<p/>
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.
<p/>
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.
</p>
<p><i>[2018-04-23 Priority set to 2 after discussion on the reflector.]</i></p>


<p><i>[2018-08-23 Batavia Issues processing]</i></p>

<p><a href="https://wg21.link/N3110">N3110</a> also touches on this.</p>
<p>Nico to survey the enums in the library and report back on which ones should be class.</p>

<p><i>[2019 Cologne Wednesday night]</i></p>

<p>Changing existing enums to class enums is an ABI break on some platforms; current wording does not require the use of enums. See N3110.</p>
<p>Daniel to provide requirements tables, Jonathan to assist. Reduce priority to 3</p>


<p id="res-3092"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4727">N4727</a>.</p>

<ol>
<li><p>Edit 16.3.3.3.3 <a href="https://wg21.link/bitmask.types">[bitmask.types]</a> as indicated:</p>
<blockquote>
<p>
-2- The bitmask type <code><i>bitmask</i></code> can be written:
</p>
<blockquote><pre>
<i>// For exposition only.</i>
<i>// </i>int_type<i> is an integral type capable of representing all values of the bitmask type.</i>
<del>enum</del><ins><i>E</i></ins> bitmask : int_type {
  V<sub>0</sub> = 1 &lt;&lt; 0, V<sub>1</sub> = 1 &lt;&lt; 1, V<sub>2</sub> = 1 &lt;&lt; 2, V<sub>3</sub> = 1 &lt;&lt; 3, .....
};
[&hellip;]
</pre></blockquote>
<p>
-3- Here, <ins><code><i>E</i></code> may represent either <code>enum</code> or <code>enum class</code> (the choice is implementation-defined 
unless otherwise specified), and</ins> the names <code><i>C</i><sub>0</sub></code>, <code><i>C</i><sub>1</sub></code>, etc. represent 
<i>bitmask elements</i> for this particular bitmask type. <ins>The zero value <code><i>bitmask</i>{}</code> is used to represent an 
<i>empty bitmask</i>, in which no bitmask elements are set.</ins> All <del>such</del><ins>bitmask</ins> elements have distinct, 
nonzero values such that, for any pair <code><i>C<sub>i</sub></i></code> and <code><i>C<sub>j</sub></i></code> where 
<code><i>i</i> &ne; <i>j</i></code>, <code><i>C<sub>i</sub></i> &amp; <i>C<sub>i</sub></i></code> is nonzero and 
<code><i>C<sub>i</sub></i> &amp; <i>C<sub>j</sub></i></code> is zero. <del>Additionally, the value <code>0</code> is used to represent 
an <i>empty bitmask</i>, in which no bitmask elements are set.</del>
</p>
</blockquote>
</li>
</ol>





</body>
</html>
