This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 907. Bitset's immutable element retrieval is inconsistently defined

Section: 20.9.2.3 [bitset.members] Status: C++11 Submitter: Daniel Krügler Opened: 2008-09-26 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [bitset.members].

View all issues with C++11 status.

Discussion:

The current standard 14882::2003(E) as well as the current draft N2723 have in common a contradiction of the operational semantics of member function `test` 20.9.2.3 [bitset.members] p.56-58 and the immutable member `operator[]` overload 20.9.2.3 [bitset.members] p.64-66 (all references are defined in terms of N2723):

1.     bool test(size_t pos) const;

   > Requires: `pos` is valid

   > Throws: `out_of_range` if `pos` does not correspond to a valid bit position.

   > Returns: `true` if the bit at position `pos` in `*this` has the value one.

2.     constexpr bool operator[](size_t pos) const;

   > Requires: `pos` shall be valid.

   > Throws: nothing.

   > Returns: `test(pos)`.

Three interpretations:

1. The `operator[]` overload is indeed allowed to throw an exception (via `test()`, if `pos` corresponds to an invalid bit position) which does not leave the call frame. In this case this function cannot be a `constexpr` function, because `test()` is not, due to 7.7 [expr.const]/2, last bullet.
2. The intend was not to throw an exception in `test` in case of an invalid bit position. There is only little evidence for this interpretation.
3. The intend was that `operator[]` should not throw any exception, but that `test` has the contract to do so, if the provided bit position is invalid.

The problem became worse, because issue 720 recently voted into WP argued that member `test` logically must be a `constexpr` function, because it was used to define the semantics of another `constexpr` function (the `operator[]` overload).

Three alternatives are proposed, corresponding to the three bullets (A), (B), and (C), the author suggests to follow proposal (C).

Proposed alternatives:

1. Remove the `constexpr` specifier in front of `operator[]` overload and undo that of member `test` (assuming 720 is accepted) in both the class declaration 20.9.2 [template.bitset]/1 and in the member description before 20.9.2.3 [bitset.members]/56 and before /64 to read:

   >     constexpr bool test(size_t pos) const;
   >     ..
   >     constexpr bool operator[](size_t pos) const;

   Change the throws clause of p. 65 to read:

   > Throws: nothing `out_of_range` if `pos` does not correspond to a valid bit position.

2. Replace the throws clause p. 57 to read:

   > Throws: `out_of_range` if `pos` does not correspond to a valid bit position nothing.

3. Undo the addition of the `constexpr` specifier to the `test` member function in both class declaration 20.9.2 [template.bitset]/1 and in the member description before 20.9.2.3 [bitset.members]/56, assuming that 720 was applied.

   >     constexpr bool test(size_t pos) const;

   Change the returns clause p. 66 to read:

   > Returns: `test(pos)` `true` if the bit at position `pos` in `*this` has the value one, otherwise `false`.

[ Post Summit: ]

> Lawrence: proposed resolutions A, B, C are mutually exclusive.

> Recommend Review with option C.

[ Batavia (2009-05): ]

> We agree with the proposed resolution. Move to Tentatively Ready.

Proposed resolution:

1. […]
2. […]

3. Undo the addition of the `constexpr` specifier to the `test` member function in both class declaration 20.9.2 [template.bitset] p.1 and in the member description before 20.9.2.3 [bitset.members] p.56, assuming that 720 was applied.

   >     constexpr bool test(size_t pos) const;

   Change the returns clause p. 66 to read:

   > Returns: `test(pos)` `true` if the bit at position `pos` in `*this` has the value one, otherwise `false`.