2015-12-14 26 views
26

Data la seguente dichiarazione nel namespace globale:Autoinizializzazione di una variabile constexpr statica, è ben formata?

constexpr int x = x; 

È questo il ben formato?

Il progetto C++ 14 sezione standard 3.6.2[basic.start.init] detto:

variabili con durata statica stoccaggio (3.7.1) o durata di conservazione filo (3.7.2) deve essere inizializzato a zero (8.5) prima di qualsiasi altra inizializzazione. [...]

Cosa sembra rendere esempio ben definita è che x viene inizializzato con il proprio valore durante l'inizializzazione costante che sarà 0 dovuta a zero inizializzazione.

È davvero così? clang accepts this code mentre gcc produces a diagnostic:

error: the value of 'x' is not usable in a constant expression 
constexpr int x = x; 
       ^
+2

Non è mai un comportamento indefinito. –

+0

@ T.C. quando ho menzionato UB, stavo pensando a [questo caso] (http://stackoverflow.com/q/14935722/1708801) e alla relativa [versione C++ 14 qui] (http://stackoverflow.com/q/ 23415661/1708801). All'inizio avevo fatto riferimento a loro nella domanda, ma mi sembrava che fosse meno chiaro. –

+3

Certo, ma in questo contesto, tutto ciò che sarebbe UB non è un'espressione costante, rendendo invece l'inizializzazione mal formata. –

risposta

23

Ciò è stato chiarito realizzando mal formata da defect report 2026: Zero-initialization and constexpr che chiede:

Secondo 3.6.2 [basic.start.init] paragrafo 2,

Variabili con durata di memorizzazione statica (3.7.1 [basic.stc.static]) o durata memorizzazione thread (3.7.2 [basic.stc.thread]) deve essere inizializzata a zero (8.5 [dcl.init]) prima di ogni altra inizializzazione .

Ciò vale anche per l'inizializzazione costante? Ad esempio, dovrebbe essere ben formato, basandosi sulla presunta inizializzazione dello zero che precede l'inizializzazione costante?

constexpr int i = i; 
struct s { 
    constexpr s() : v(v) { } 
    int v; 
}; 
constexpr s s1; 

La nota prima che la proposta di delibera dice:

CWG hanno convenuto che l'inizializzazione costante dovrebbe essere considerato come accade invece di zero inizializzazione in questi casi, rendendo le dichiarazioni mal formate.

e la risoluzione proposta chiarisce e tra molti cambiamenti, rimuove la seguente formulazione:

variabili con durata statica stoccaggio (3.7.1) o durata di conservazione filo (3.7.2) è zero inizializzato (8.5) prima di qualsiasi altra inizializzazione. [...]

e aggiunge la seguente formulazione:

Se inizializzazione costante non viene eseguita, una variabile con durata di conservazione statica (3.7.1 [basic.stc.statico]) o durata della memorizzazione del thread (3.7.2 [basic.stc.thread]) è inizializzato a zero (8.5 [dcl.init]). [...]

Si tratta di un grande cambiamento, si rinomina [basic.start.init]-[basic.start.static] e ha creato una nuova sezione [basic.start.dynamic ] e modifica [stmt.dcl]

Problemi correlati