Title
Instantiating templates in §[rand] with int8_t/uint8_t is undefined behavior
Status
new
Section
[rand.req.genl]
Submitter
Peter Dimov

Created on 2024-05-25.00:00:00 last changed 4 months ago

Messages

Date: 2024-05-26.09:17:27

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

  1. Modify [rand.req.genl] as indicated:

    -1- Throughout this subclause [rand], the effect of instantiating a template:

    1. […]

    2. (1.4) — that has a template type parameter named RealType is undefined unless the corresponding template argument is cv-unqualified and is one of float, double, or long double.

    3. (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 ([basic.fundamental])one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long.

    4. (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 ([basic.fundamental])one of unsigned short, unsigned int, unsigned long, or unsigned long long.

Option B: Make ill-formed.

  1. Modify [rand.req.genl] as indicated:

    -1- Throughout this subclause [rand], the effect of instantiating a template:

    1. […]

    2. (1.4) — that has a template type parameter named RealType is undefined unless the corresponding template argument is cv-unqualified and is one of float, double, or long double.

    3. (1.5) — that has a template type parameter named IntType renders the program ill-formedis 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.

    4. (1.6) — that has a template type parameter named UIntType renders the program ill-formedis undefined unless the corresponding template argument is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned long long.

Date: 2024-05-15.00:00:00

[ 2024-05-26; Daniel comments ]

I think that all violations of the bullets [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).

Given that I also think that we should consider to either normatively extend all of (1.4), (1.5), and (1.6) to corresponding extended floating point types and extended (unsigned) integer types, or to the minimum make these extended types conditionally-supported with implementation-defined semantics (A word of power that is used at several places).

Date: 2024-05-25.00:00:00

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 [rand.req.genl] bullet (1.5):

-1- Throughout this subclause [rand], the effect of instantiating a template:

  1. […]

  2. (1.4) — that has a template type parameter named RealType is undefined unless the corresponding template argument is cv-unqualified and is one of float, double, or long double.

  3. (1.5) — 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.

  4. (1.6) — that has a template type parameter named UIntType is undefined unless the corresponding template argument is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned 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 of uint8_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.

History
Date User Action Args
2024-05-26 09:17:27adminsetmessages: + msg14161
2024-05-26 09:17:27adminsetmessages: + msg14160
2024-05-25 00:00:00admincreate