On Thu, 26 Feb 2026 at 21:42, Jan Schultke via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


On Thu, 26 Feb 2026 at 22:28, Jens Maurer <jens.maurer@gmx.net> wrote:


On 2/26/26 17:44, Jan Schultke via Std-Proposals wrote:
> Hi,
>
> I'm working on another proposal that may likely be a "slam dunk":
> https://isocpp.org/files/papers/D4037R0.html <https://isocpp.org/files/papers/D4037R0.html>
>
> In short, this allows std::uniform_int_distribution<unsigned char> and such things, which is currently IFNDR/compile-time UB. https://cplusplus.github.io/LWG/issue2326 <https://cplusplus.github.io/LWG/issue2326> previously attempted the same, but was closed as NAD because it was considered a feature request.
>
> I'm mainly posting here to see if anyone has some historical context into why this was ever disallowed, or in case someone has a good reason not to allow it now; I don't see any good reason.

For generators, using "unsigned char" and friends seems to make zero sense,
in particular with the generators supplied in the standard.  Making this
diagnosable seems to be a plus.


I can see why someone wants to have a

  std::uniform_int_distribution<unsigned char>(0, 255)

which is the same as

  std::uniform_int_distribution<unsigned int>(0, 255)

except for the difference in return type; the value range is the same.

The wording in the paper isn't sufficiently differentiating those two
cases.

You mean wording as in the proposed wording changes, or the discussion in the paper? I think the proposed wording changes are clear.

In any case, as I've said to Sebastian, I think there is no motivation for disallowing the instantiation of engines using single-byte types. One could equally argue that certain instantiations with short should be disallowed because they are of low quality, but that seems like rather pointless policing to me.

If it protects users from making an easy but harmful mistake, it's not pointless. As Bjorn noted, none of our engines are tuned for producing 8-bit numbers (and std::random_device always gives you more bits than that).

There is no reason to enable users to do this:

std::linear_congruential_engine<uint8_t, 123, 0, 127> e;
std::uniform_int_distribution<uint64_t> d;
return d(e);

This is just bad. If you run it 1000 times you get 8 different numbers in a loop. That's not something useful to provide.

 
One could also make a similar domain-specific argument that instantiating std::string_view with 64-bit or 128-bit integers should be disallowed (even if char_traits is provided) because 64 bits or 128 bits is excessive and weird for a character type. It's not really our job to declare what template arguments are "too bad practice" to be provided.

When it comes to <random>, I disagree.
 
If you want to instantiate std::array<std::nullptr_t, 1024>, as dumb as it is, go for it.

As things stand, GCC and Clang permit the use of 8-bit types in generators, and I don't see a compelling reason to disallow it. The implementation works and the wording can easily work.

 They permit it because it's undefined according to the standard, so nobody bothered to stop it.

We should at least consider if we want to change that, and that should be discussed as part of any proposal.