C'è sorprendentemente poco nello standard su questo. A proposito di tutto abbiamo sentito parlare di ridichiarazione è:
[C++11: 3.1/1]:
Una dichiarazione (clausola 7) può introdurre uno o più nomi in un'unità di traduzione o nomi ridichiarare introdotti da precedenti dichiarazioni. [..]
e l'unica parte rilevante della semantica auto
s':
[C++11: 7.1.6.4/3]:
In caso contrario, il tipo della variabile si deduce dalla sua inizializzazione. [..]
(ricordandoci che il tipo di x
è int
).
Sappiamo che una variabile deve essere dato lo stesso tipo per tutte le dichiarazioni:
[C++11: 3.5/10]:
Dopo tutte le regolazioni di tipi (durante il quale typedefs (7.1.3) sono sostituite dalle loro definizioni), i tipi specificato da tutte le dichiarazioni che fanno riferimento a una determinata variabile o funzione deve essere identico a, eccetto che le dichiarazioni per un oggetto matrice possono specificare tipi di array che differiscono dalla presenza o dall'assenza di un allineamento di matrice maggiore (8.3.4). Una violazione di questa regola sull'identità del tipo non richiede una diagnostica.
e il "dopo tutte le rettifiche di tipi" dovrebbero prendersi cura di qualsiasi domanda riguardante auto
s' la partecipazione a tutto questo; la mia interpretazione, quindi, è che è intrinsecamente una ridichiarazione valida (e definizione) dello x
nell'ambito globale con tipo int
e che Clang è corretto. Anche se noi proponiamo che auto
non conta come "la regolazione di tipo", dal momento che non è richiesto diagnostica, nella peggiore delle ipotesi tutti implementazioni elencati sono conformi a modo loro.
credo GCC e Visual Studio sta assumendo i seguenti come ispirazione:
[C++11: 7.1.6.4/5]:
Un programma che utilizza auto
in un contesto non esplicitamente consentito in questa sezione è mal formati.
e hellip, ma penso che questo sia miope. Sembra improbabile che il linguaggio standard abbia lo scopo di proibire le consuete regole di redeclaration, solo perché non sono ripetute o esplicitamente referenziate da 7.1.6.4
.
C++ 14 aggiunge formulazione che si riferisce alle dichiarazioni di funzioni con i tipi dedotte:
[C++14: 7.1.6.4/13]:
Redeclarations o specializzazioni di una funzione o di modello di funzione con un tipo di ritorno dichiarato che utilizza un tipo di segnaposto deve inoltre usa quel segnaposto, non un tipo dedotto. [..]
Per simmetria si potrebbe suggerire che, nel vostro int
caso, si intende che GCC e VS siano corrette nel respingere il programma. Tuttavia, questa è una caratteristica diversa (poiché la detrazione non può essere applicata alle mere dichiarazioni) e quindi uno scenario diverso.
In entrambi i casi, una migliore formulazione standard sarebbe d'aiuto. Lo considero un difetto editoriale [ragionevolmente minore].
Penso che sia ciò che intende proibire, per escludere costrutti come "extern int i; auto i = decltype (i)(); ', con cui le implementazioni potrebbero avere molti problemi. O peggio, "extern int i; auto j = decltype (i)(); auto i = decltype (j)(); '. Ciò viola le restrizioni su una variabile dichiarata come 'auto' che appare nel proprio inizializzatore? – hvd
@hvd: Non vedo un grosso problema con nessuno di questi. 'i' è già in ambito e il suo tipo è noto, in entrambi i casi. –
Eppure clang rifiuta il primo ('i' appare in modo lessicale nel proprio inizializzatore, e questo è il modo in cui implementa la regola) e accetta il secondo. – hvd