2015-07-03 5 views
17

Раздел 26.5.1.1 пункт Генератор UIntType противоречие 1 из стандарта C++ 11 (N3242) говорит:C++ 11 случайное число

В данном подпункте 26.5, эффект инстанцировании шаблона:

[...]

е), который имеет параметр типа шаблона с именем UIntType является не определен, если соответствующий шаблон аргумент является резюме, неквалифицированные и является одним из unsigned short, unsigned int, unsigned long, или unsigned long long.

И он определяет линейный конгруэнтный генератор в 26.5.3.1. Определение класса начинается так:

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

minstd_rand0, кажется, нарушают это ограничение:

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

Как он использует uint_fast32_t (который не гарантированно будет один из unsigned short, unsigned int, unsigned long, или unsigned long long) в minstd_rand0 для параметра шаблона с именем UIntType, он имеет неопределенный эффект для #include <random> или, по крайней мере, для использования minstd_rand0. Эта проблема также относится к другим предопределенным RNG, и, похоже, она не исправлена ​​в C++ 14.

Мои вопросы:

  • Является ли это на самом деле противоречие (или, скорее экстремальное количество неопределенного поведения), или я что-то пропустил?
  • Оказалось ли это в отчете о дефектах?

Edit: Я заметил, что this отчет дефект, как представляется, связаны с этой проблемой.

+0

Ну, предложение * Обязательное поведение *, которое следует за ним, возможно, обязательно требует использования такой вещи, чтобы быть четко определенным. Независимо от того, существует ли реальная система, в которой 'uint_fast32_t' является * не * одним из этих типов? –

+0

@ T.C. Полагаю, что это возможно, но я думаю, что для этого требуется только 10000-й вызов. Вызов 10001th все равно может вызвать проблему (или, если на то пошло, двигатель, который не был сконфигурирован по умолчанию). – qbt937

+0

@ T.C. MSVC может определять 'uint_fast32_t', используя свой' unsigned __int32' тип (я не знаю, поскольку я не использую MSVC). Я согласен, что этот вопрос академичен. – qbt937

ответ

0

Я не эксперт, но я отвечаю, что да, это дефект, если вы правы, что uint_fast32_t не обязательно должен быть одним из этих типов в соответствии со стандартом.

Предложение, указанное в выпуске 2336 NAD, которое вы указали, также должно устранить этот дефект.

1

Да и нет. В разделе 18.4.1, uint_fast32_t Должен быть псевдоним целого типа без знака. Хотя единственные неподписанные целые типы в C++ - это unsigned char, short, int, long, long, long (3.9.1). Таким образом, единственный сценарий, который вы упомянули, может быть противоречием в том, что char как-то 32-битный или более широкий и и uint_fast32_t определяется как псевдоним для unsigned char.

1

uint_fast32_t указан как самый быстрый целочисленный беззнаковый тип с шириной не менее 32 бит.

В системе типа C++ оба типа символов и целочисленных типов являются целыми типами, но типы символов не являются целыми типами (и наоборот).

И, наконец, целые типы без знака - это те, которые перечислены для случайных генераторов.

Мое заключение заключается в том, что использование uint_fast32_t соответствует стандарту (если только я не пропустил какую-либо часть стандарта, где для uint_fast32_t не допускается тип nonstsndard, или для определения целочисленного типа для включения нестандартных типов).

Однако я считаю, что спецификация должна быть исправлена, чтобы попытаться избежать неоднозначных интерпретаций.

Смежные вопросы