<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3977: constexpr and noexcept for operators for bitmask types</title>
<meta property="og:title" content="Issue 3977: constexpr and noexcept for operators for bitmask types">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3977.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#New">New</a> status.</em></p>
<h3 id="3977"><a href="lwg-active.html#3977">3977</a>. <code>constexpr</code> and <code>noexcept</code> for operators for 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#New">New</a>
 <b>Submitter:</b> Jiang An <b>Opened:</b> 2023-08-19 <b>Last modified:</b> 2024-02-22</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#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Currently, no operator in 16.3.3.3.3 <a href="https://wg21.link/bitmask.types">[bitmask.types]</a>/2 is specified as <code>noexcept</code>, and the compound assignment 
operators are not specified as <code>constexpr</code>.
<p/>
Implementations are divergent on this. E.g., MSVC STL 
<a href="https://github.com/microsoft/STL/blob/8f67ece4a654625220642c92fa029a5cfc77afa8/stl/inc/type_traits#L2266-L2297">consistently 
marks them <code>constexpr</code> and <code>noexcept</code></a> (given MSVC STL doesn't support pre-C++14 modes), while libstdc++'s 
<a href="https://github.com/gcc-mirror/gcc/blob/fab08d12b40ad637c5a4ce8e026fb43cd3f0fad1/libstdc%2B%2B-v3/include/bits/regex_constants.h#L395-L408">compound 
assignment operators for <code>match_flag_type</code></a> are <code>constexpr</code> since C++14 but lack <code>noexcept</code>, and 
<a href="https://github.com/gcc-mirror/gcc/blob/fab08d12b40ad637c5a4ce8e026fb43cd3f0fad1/libstdc%2B%2B-v3/include/std/future#L176-L183">the 
operators for <code>launch</code></a> are <code>noexcept</code> but not <code>constexpr</code>.
<p/>
I think it's better to ensure more consistency be integer types and non-integer bitmask types, i.e., require the 
compound assignment operators to be <code>constexpr</code> (only available in C++14 and later) and all operators to be <code>noexcept</code>.
</p>

<p><i>[2024-02-22; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll in September 2023.
</p>
<p><i>[Jonathan commented]</i></p>

<p>
"The proposed change only affects an example showing a possible way to implement
a made-up example type. It doesn't change any requirements on bitmask types,
or change anything for any of the bitmask types defined in the standard library.
It doesn't say that implementing them without noexcept and constexpr would be
invalid.
This change has no normative effect and certainly doesn't achieve the stated
aim of requiring these assignments to be constexpr and non-throwing."
</p>
<p><i>[Casey agreed]</i></p>

<p>
"We should strike paragraph two completely and write up the actual requirements
that a bitmask type is required to meet, but that's a lot of work for someone."
</p>



<p id="res-3977"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4958" title=" Working Draft, Programming Languages — C++">N4958</a>.
</p>

<ol>

<li><p>Modify 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>int_type is an integral type capable of representing all values of the bitmask type.</i>
enum <i>bitmask</i> : int_type {
  <i>V</i><sub>0</sub> = 1 &lt;&lt; 0, <i>V</i><sub>1</sub> = 1 &lt;&lt; 1, <i>V</i><sub>2</sub> = 1 &lt;&lt; 2, <i>V</i><sub>3</sub> = 1 &lt;&lt; 3, &hellip;
};

inline constexpr <i>bitmask</i> <i>C</i><sub>0</sub>(<i>V</i><sub>0</sub>);
inline constexpr <i>bitmask</i> <i>C</i><sub>1</sub>(<i>V</i><sub>1</sub>);
inline constexpr <i>bitmask</i> <i>C</i><sub>2</sub>(<i>V</i><sub>2</sub>);
inline constexpr <i>bitmask</i> <i>C</i><sub>3</sub>(<i>V</i><sub>3</sub>);

[&hellip;]

constexpr bitmask operator&amp;(bitmask X, bitmask Y) <ins>noexcept</ins> {
  return static_cast&lt;bitmask&gt;(
    static_cast&lt;int_type&gt;(X) &amp; static_cast&lt;int_type&gt;(Y));
}
constexpr bitmask operator|(bitmask X, bitmask Y) <ins>noexcept</ins> {
  return static_cast&lt;bitmask&gt;(
    static_cast&lt;int_type&gt;(X) | static_cast&lt;int_type&gt;(Y));
}
constexpr bitmask operator^(bitmask X, bitmask Y) <ins>noexcept</ins> {
  return static_cast&lt;bitmask&gt;(
    static_cast&lt;int_type&gt;(X) ^ static_cast&lt;int_type&gt;(Y));
}
constexpr bitmask operator~(bitmask X) <ins>noexcept</ins> {
  return static_cast&lt;bitmask&gt;(~static_cast&lt;int_type&gt;(X));
}
<ins>constexpr</ins> bitmask&amp; operator&amp;=(bitmask&amp; X, bitmask Y) <ins>noexcept</ins> {
  X = X &amp; Y; return X;
}
<ins>constexpr</ins> bitmask&amp; operator|=(bitmask&amp; X, bitmask Y) <ins>noexcept</ins> {
  X = X | Y; return X;
}
<ins>constexpr</ins> bitmask&amp; operator^=(bitmask&amp; X, bitmask Y) <ins>noexcept</ins> {
  X = X ^ Y; return X;
}
</pre>
</blockquote>
</blockquote>

</li>

</ol>





</body>
</html>
