int8_t
/uint8_t
is undefined behaviorSection: 29.5.3.1 [rand.req.genl] Status: New Submitter: Peter Dimov Opened: 2024-05-25 Last modified: 2024-05-26
Priority: Not Prioritized
View all other issues in [rand.req.genl].
View all issues with New status.
Discussion:
As pointed out in LWG issue 2326 (closed as NAD) and
on reddit,
instantiating e.g. uniform_int_distribution<uint8_t>
is undefined behavior
because of the requirement 29.5.3.1 [rand.req.genl] bullet (1.5):
-1- Throughout this subclause 29.5 [rand], the effect of instantiating a template:
[…]
(1.4) — that has a template type parameter named
RealType
is undefined unless the corresponding template argument is cv-unqualified and is one offloat
,double
, orlong double
.(1.5) — that has a template type parameter named
IntType
is undefined unless the corresponding template argument is cv-unqualified and is one ofshort
,int
,long
,long long
,unsigned short
,unsigned int
,unsigned long
, orunsigned long long
.(1.6) — that has a template type parameter named
UIntType
is undefined unless the corresponding template argument is cv-unqualified and is one ofunsigned short
,unsigned int
,unsigned long
, orunsigned long long
.
This is, in my opinion, a defect; such uses should either be rejected at compile time (made ill-formed), or permitted (as 2326 proposes.)
UB here has undesirable safety implications, because it's possible to write code that produces a random, or a seemingly random, sequence ofuint8_t
numbers on platform A, but an arbitrarily non-random
sequence on platform B (e.g. all zeroes.)
If that sequence is then used in e.g. a cryptographic algorithm, bad
things will happen on platform B, and the tests on platform A won't
catch the issue.
[2024-05-26; Daniel comments]
I think that all violations of the bullets 29.5.3.1 [rand.req.genl] (1.4), (1.5), and (1.6)
are missed opportunities of Mandates (That is: Make the program ill-formed), because
they can be all checked (easily) at compile-time, regardless whether we agree on
the question to support int8_t
/uint8_t
(Violations of (1.1), (1.2), and (1.3)
still have to be remain undefined because of additional runtime requirements imposed).
Proposed resolution:
This wording is relative to N4981.
[Drafting Note: Two mutually exclusive options are prepared, depicted below by Option A and Option B, respectively.]
Option A: As suggested in issue LWG 2326
Modify 29.5.3.1 [rand.req.genl] as indicated:
-1- Throughout this subclause 29.5 [rand], the effect of instantiating a template:
[…]
(1.4) — that has a template type parameter named
RealType
is undefined unless the corresponding template argument is cv-unqualified and is one offloat
,double
, orlong double
.(1.5) — 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.8.2 [basic.fundamental])one of.short
,int
,long
,long long
,unsigned short
,unsigned int
,unsigned long
, orunsigned long long
(1.6) — 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.8.2 [basic.fundamental])one of.unsigned short
,unsigned int
,unsigned long
, orunsigned long long
Option B: Make ill-formed.
Modify 29.5.3.1 [rand.req.genl] as indicated:
-1- Throughout this subclause 29.5 [rand], the effect of instantiating a template:
[…]
(1.4) — that has a template type parameter named
RealType
is undefined unless the corresponding template argument is cv-unqualified and is one offloat
,double
, orlong double
.(1.5) — that has a template type parameter named
IntType
renders the program ill-formedis undefinedunless the corresponding template argument is cv-unqualified and is one ofshort
,int
,long
,long long
,unsigned short
,unsigned int
,unsigned long
, orunsigned long long
.(1.6) — that has a template type parameter named
UIntType
renders the program ill-formedis undefinedunless the corresponding template argument is cv-unqualified and is one ofunsigned short
,unsigned int
,unsigned long
, orunsigned long long
.