2015-11-09 18 views
10

Si consideri il seguente:Una conversione enum fuori intervallo produce un valore al di fuori del tipo sottostante?

#include <iostream> 

enum class E : bool { A, B }; 

void foo(E e) 
{ 
    switch(e) 
    { 
    case E::A: break; 
    case E::B: break; 
    default: std::cout << "aha\n"; 
    } 
} 

int main() 
{ 
    foo(static_cast<E>(3)); 
} 

La mia domanda è: il caso default può essere attivato, vale a dire il programma genera in uscita?

Il punto delicato in N3936 sembra essere specifica di static_cast quando si converte un numero intero fuori gamma di enumerazione tipo, [expr.static.cast]/10:

Un valore integrale o il tipo di enumerazione può essere convertito esplicitamente in un tipo di enumerazione. Il valore è invariato se il valore originale è compreso nell'intervallo dei valori di enumerazione. In caso contrario, il valore risultante non è specificato (e potrebbe non essere compreso nell'intervallo).

Il testo in grassetto non dice esplicitamente che il valore deve essere ancora compreso nell'intervallo del tipo sottostante, ma mi chiedo se sia stato previsto che lo abbia fatto.

+0

Nota: non intendo limitare la mia domanda a questo esempio specifico - se possibile, una risposta che copra anche le enumerazioni di tipo sottostante non fisso sarebbe ottima –

+1

Questo è UB di [CWG 1766] (http://wg21.link/CWG1766). –

+0

Sì, potrebbe, dato il cast non definito. Almeno VS2013 effettivamente stampa "aha" – Niall

risposta

6

Penso che [expr.static.cast]/10 risponda a questo. Nella bozza di lavoro corrente, si legge:

Un valore di tipo integrale o di enumerazione può essere convertito in modo esplicito in un tipo di enumerazione completo. Il valore è invariato se il valore originale è compreso nell'intervallo dei valori di enumerazione (7.2). In caso contrario, il comportamento non è definito.

In altre parole, il programma è indefinito comportamento, poiché la portata di un tipo di enumerazione di tipo fisso sottostante (nel caso: bool) è la gamma di tale tipo.

La modifica dal preventivo è stata interessata dal numero resolution of CWG1766 (issues link); nota che il problema è riconosciuto come un difetto (quindi dovresti dimenticare la dicitura originale).

Problemi correlati