184. numeric_limits<bool> wording problems

Section: 21.3.4.2 [numeric.special] Status: CD1 Submitter: Gabriel Dos Reis Opened: 1999-07-21 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [numeric.special].

View all issues with CD1 status.

Discussion:

bools are defined by the standard to be of integer types, as per 6.7.1 [basic.fundamental] paragraph 7. However "integer types" seems to have a special meaning for the author of 18.2. The net effect is an unclear and confusing specification for numeric_limits<bool> as evidenced below.

18.2.1.2/7 says numeric_limits<>::digits is, for built-in integer types, the number of non-sign bits in the representation.

4.5/4 states that a bool promotes to int ; whereas 4.12/1 says any non zero arithmetical value converts to true.

I don't think it makes sense at all to require numeric_limits<bool>::digits and numeric_limits<bool>::digits10 to be meaningful.

The standard defines what constitutes a signed (resp. unsigned) integer types. It doesn't categorize bool as being signed or unsigned. And the set of values of bool type has only two elements.

I don't think it makes sense to require numeric_limits<bool>::is_signed to be meaningful.

18.2.1.2/18 for numeric_limits<integer_type>::radix  says:

For integer types, specifies the base of the representation.186)

This disposition is at best misleading and confusing for the standard requires a "pure binary numeration system" for integer types as per 3.9.1/7

The footnote 186) says: "Distinguishes types with base other than 2 (e.g BCD)."  This also erroneous as the standard never defines any integer types with base representation other than 2.

Furthermore, numeric_limits<bool>::is_modulo and numeric_limits<bool>::is_signed have similar problems.

Proposed resolution:

Append to the end of 21.3.4.2 [numeric.special]:

The specialization for bool shall be provided as follows:

    namespace std {
       template<> class numeric_limits<bool> {
       public:
         static const bool is_specialized = true;
         static bool min() throw() { return false; }
         static bool max() throw() { return true; }

         static const int  digits = 1;
         static const int  digits10 = 0;
         static const bool is_signed = false;
         static const bool is_integer = true;
         static const bool is_exact = true;
         static const int  radix = 2;
         static bool epsilon() throw() { return 0; }
         static bool round_error() throw() { return 0; }

         static const int  min_exponent = 0;
         static const int  min_exponent10 = 0;
         static const int  max_exponent = 0;
         static const int  max_exponent10 = 0;

         static const bool has_infinity = false;
         static const bool has_quiet_NaN = false;
         static const bool has_signaling_NaN = false;
         static const float_denorm_style has_denorm = denorm_absent;
         static const bool has_denorm_loss = false;
         static bool infinity() throw() { return 0; }
         static bool quiet_NaN() throw() { return 0; }
         static bool signaling_NaN() throw() { return 0; }
         static bool denorm_min() throw() { return 0; }

         static const bool is_iec559 = false;
         static const bool is_bounded = true;
         static const bool is_modulo = false;

         static const bool traps = false;
         static const bool tinyness_before = false;
         static const float_round_style round_style = round_toward_zero;
       };
     }

[Tokyo:  The LWG desires wording that specifies exact values rather than more general wording in the original proposed resolution.]

[Post-Tokyo:  At the request of the LWG in Tokyo, Nico Josuttis provided the above wording.]