Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 random number generator UIntType contradiction

Section 26.5.1.1 paragraph 1 of the C++11 standard (N3242) says:

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

[...]

f) 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.

And it defines the linear congruential generator in 26.5.3.1. The definition of the class starts like this:

template<class UIntType, UIntType a, UIntType c, UIntType m>
class linear_congruential_engine

minstd_rand0 seems to violate this restriction:

typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
    minstd_rand0;

As it uses uint_fast32_t (which isn't guaranteed to be one of unsigned short, unsigned int, unsigned long, or unsigned long long) in minstd_rand0 for a template parameter named UIntType, it appears to have undefined effect to #include <random>, or at least to use minstd_rand0. This problem applies to other predefined RNGs as well, and it does not appear to be fixed in C++14.

My questions are:

  • Is this really a contradiction (or rather an extreme amount of undefined behaviour), or have I missed something?
  • Has this been mentioned in a defect report?

Edit: I have noticed that this defect report seems to be related to this problem.

like image 776
qbt937 Avatar asked Jul 03 '15 02:07

qbt937


2 Answers

Yes and no. Per section 18.4.1, uint_fast32_t Has to be an alias to an unsigned integer type. While the only unsigned integer types in C++ are unsigned char, short, int, long, long, long (3.9.1) So the only scenario that the section you mentioned can be a contradiction is that char is somehow 32-bits or wider and and uint_fast32_t is defined to an alias to unsigned char.

like image 136
Yan Zhou Avatar answered Sep 21 '22 05:09

Yan Zhou


uint_fast32_t is specified to be the fastest unsigned integer type with width of at least 32 bits.

In C++ type system, both character and integer types are integral types, but character types are not integer types (nor vice-versa).

Finally, unsigned integer types are exactly the ones enumerated for random generators.

My conclusion is that using uint_fast32_t complies with the standard (unless I missed some part of the standard where it is specifically allowed for uint_fast32_t to be a nonstsndard type, or for the definition of integer type to include nonstandard types).

However, I believe the spec should be fixed to try to avoid ambiguous interpretations.

like image 45
Juan Avatar answered Sep 25 '22 05:09

Juan