2326. uniform_int_distribution<unsigned char> should be permitted

Section: 29.6.1.1 [rand.req.genl] Status: NAD Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2017-02-02

Priority: 2

View all issues with NAD status.

Discussion:

29.6.1.1 [rand.req.genl]/1 says: "Throughout this subclause 26.5, the effect of instantiating a template [...] that has a template type parameter named IntType is undefined unless the corresponding template argument is cv-unqualified and is one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long." 29.6.8.2.1 [rand.dist.uni.int] specifies template<class IntType = int> class uniform_int_distribution, so this forbids uniform_int_distribution<char/signed char/unsigned char>.

I am not aware of anything in <random> that works with 16-bit integers but fails with 8-bit integers, so I suspect that IntType and UIntType could simply be extended to permit the char family. Alternatively, this change could be limited to uniform_int_distribution alone, where it is definitely safe. A <random> expert should decide which change is best.

[2015-04-04 Geoffrey provides wording]

I think it's time to call the question; it's just silly that we have a random number library with no natural way to generate random bytes. However, I don't think it's sufficient to fix only uniform_int_distribution, or even all of IntType. At a bare minimum we need to also fix independent_bits_engine (arguably the cleanest way of generating a random byte) and that's specified in terms of UIntType.

The wording provided below is equivalent to adding unsigned char to item "f" and adding signed char and unsigned char to item "e". That means it still excludes char, but I'm OK with that. If you want to generate a 1-byte number, you should probably pick a signedess, and if you want to generate a raw byte, the "true" raw byte type is unsigned char. This also excludes extended integral types and wide char types, which seem like nice-to-haves at best. I have no objection to supporting any of those types; I just picked this to simplify the wording and hopefully maximize consensus. Note that if we want to broaden IntType to permit any integral type, we'll need to decide if we want to exclude bool.

For reference, IntType is used as a parameter of the following templates:

uniform_int_distribution
binomial_distribution
geometric_distribution
negative_binomial_distribution
poisson_distribution
discrete_distribution

and UIntType is used as a parameter of the following templates:

linear_congruential_engine
mersenne_twister_engine
subtract_with_carry_engine
independent_bits_engine

[2015-9-11, Telecon]

Walter feels very strongly that this is not a defect, but a feature request.

In a previous telecon, Aaron offered to write a paper proposing this.

Jonathan offered to help.

Closing as NAD

Proposed resolution:

This wording is relative to N4296.

  1. Change in 29.6.1.1 [rand.req.genl] p1 as indicated:

    -1- Throughout this subclause 26.5, the effect of instantiating a template:

    1. […]

    2. that has a template type parameter named IntType is undefined unless the corresponding template argument is cv-unqualified and is a standard integer type (6.7.1 [basic.fundamental])one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long.

    3. that has a template type parameter named UIntType is undefined unless the corresponding template argument is cv-unqualified and is a standard unsigned integer type (6.7.1 [basic.fundamental])one of unsigned short, unsigned int, unsigned long, or unsigned long long.