2014-10-15 18 views

risposta

22

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].

+0

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

+0

@hvd: Non vedo un grosso problema con nessuno di questi. 'i' è già in ambito e il suo tipo è noto, in entrambi i casi. –

+0

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

Problemi correlati