Title
Bitset's immutable element retrieval is inconsistently defined
Status
c++11
Section
[bitset.members]
Submitter
Daniel Krügler

Created on 2008-09-26.00:00:00 last changed 162 months ago

Messages

Date: 2011-04-30.23:09:42

Proposed resolution:

  1. […]
  2. […]
  3. Undo the addition of the constexpr specifier to the test member function in both class declaration [template.bitset] p.1 and in the member description before [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.

Date: 2011-04-24.20:26:46

[ Batavia (2009-05): ]

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

Date: 2011-04-24.20:26:46

[ Post Summit: ]

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

Recommend Review with option C.

Date: 2011-04-30.23:09:42

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 [bitset.members] p.56-58 and the immutable member operator[] overload [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 [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 [template.bitset]/1 and in the member description before [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 [template.bitset]/1 and in the member description before [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.

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2011-04-24 20:26:46adminsetmessages: + msg5748
2011-04-24 20:26:46adminsetmessages: + msg5747
2011-04-24 20:26:46adminsetmessages: + msg5746
2008-09-26 00:00:00admincreate