2015-07-03 13 views
17

Sezione 26.5.1.1 comma 1, del C++ 11 standard (N3242) dice:C++ 11 generatore di numeri casuali UIntType contraddizione

In tutta questa sottoclausola 26,5, l'effetto di istanziare un modello:

[...]

f) che dispone di un parametro di tipo di modello di nome UIntType è indefinito a meno che il corrispondente modello argomento è cv-qualificato ed è uno dei unsigned short, unsigned int, 0.123.o unsigned long long.

E definisce il generatore congruenziale lineare in 26.5.3.1. La definizione della classe inizia così:

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

minstd_rand0 sembra violare questa restrizione:

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

quanto utilizza uint_fast32_t (che non è garantito per essere uno dei unsigned short, unsigned int, unsigned long, oppure unsigned long long) in minstd_rand0 per un parametro modello denominato UIntType, sembra avere un effetto indefinito su #include <random> o almeno su minstd_rand0. Questo problema si applica anche ad altri RNG predefiniti e non sembra corretto in C++ 14.

Le mie domande sono:

  • Questa è davvero una contraddizione (o meglio una quantità estrema di comportamento non definito), o sono ho perso qualcosa?
  • È stato menzionato in un rapporto sui difetti?

Edit: Ho notato che this rapporto difetto sembra essere correlato a questo problema.

+0

Bene, la clausola * Comportamento richiesto * che segue immediatamente richiede necessariamente l'utilizzo di una cosa del genere per essere ben definita. Indipendentemente da ciò, esiste un sistema reale in cui 'uint_fast32_t' è * non * uno di questi tipi? –

+0

@ T.C. Suppongo che potrebbe, ma penso che richieda solo che la 10000a invocazione sia corretta. L'invocazione 10001th potrebbe ancora causare un problema (o, per altro, un motore che non è stato costruito in modo predefinito). – qbt937

+0

@ T.C. MSVC potrebbe definire 'uint_fast32_t' usando il loro tipo' unsigned __int32' (non so come non usi MSVC). Sono d'accordo che questa domanda è accademica però. – qbt937

risposta

0

Non sono esperto, ma la mia risposta è che sì è un difetto, se è corretto che lo uint_fast32_t non deve essere uno di quei tipi secondo lo standard.

La proposta nel numero NAD 2326 cui si fa riferimento sembra risolvere anche questo difetto.

1

Sì e no. Per sezione 18.4.1, uint_fast32_t Deve essere un alias per un tipo di numero intero senza segno. Mentre i soli tipi interi non firmati in C++ sono senza carattere char, short, int, long, long, long (3.9.1) Quindi l'unico scenario in cui la sezione che hai citato può essere una contraddizione è che char è in qualche modo a 32 bit o più ampio e e uint_fast32_t è definito per un alias per il char unsigned.

1

uint_fast32_t è specificato per essere il tipo di intero senza segno più veloce con larghezza di almeno 32 bit.

Nel sistema di tipo C++, sia i caratteri che i tipi interi sono tipi interi, ma i tipi di carattere non sono tipi interi (né viceversa).

Infine, i tipi di interi senza segno sono esattamente quelli enumerati per i generatori casuali.

La mia conclusione è che l'uso di uint_fast32_t è conforme allo standard (a meno che non mi sia sfuggita una parte dello standard in cui è specificatamente consentito uint_fast32_t di essere un tipo nonstsndard, o per la definizione di tipo intero per includere tipi non standard).

Tuttavia, credo che le specifiche dovrebbero essere corrette per cercare di evitare interpretazioni ambigue.

Problemi correlati