2016-05-24 17 views
16

È consentito quanto segue dalla norma?Una variabile può essere dichiarata auto come dedotta allo stesso tipo?

#include <iostream> 

extern int a; 
auto a = 3; 

int main(int, char**) 
{ 
    std::cout << a << std::endl; 
    return 0; 
} 

clang accetta il codice. g++ reclami per dichiarazione contraddittoria.

+1

Sicuramente questo è un bug g ++ –

+0

Questo codice causa un errore anche in MS Visual Studio 2012, dicendo 'errore C2371: 'a': ridefinizione; diversi tipi di base ». – nabroyan

+0

Che dire: 'extern int a; decltype (a) a; ';) – Ajay

risposta

2

La sua non è molto chiaro per me dallo standard, ma poi, c'è questa scritta

sezione 7.1.6.4 auto identificatore
Un programma che utilizza auto in un contesto non esplicitamente consentito in questa sezione è mal formati.

Leggere meglio la sezione indicata dello standard per tutti i contesti consentiti.

Considerato questo, credo che g ++ sia corretto e clang sia sbagliato. Ma potrei sbagliarmi, potrebbe esserci una sezione separata nello standard che potrebbe implicare questo contesto, ma non riuscivo a trovarla.

+2

Ma 'auto a = 3;' questo è un contesto esplicitamente consentito. "Questo uso è permesso quando si dichiarano le variabili in un blocco (6.3), ** in scope namespace ** (3.3.6), [...]" –

+0

Forse in senso contestuale (a extern) non è applicabile? O g ++ e clang l'hanno interpretato diversamente, in questo caso il linguaggio dello standard sembra essere piuttosto lento. – Arunmu

-2

Modifica risposta: Come menzione nei commenti. Il problema in questo caso è che scrittura

external int a; 
auto a = 3; 

è lo stesso di scrittura

external int a; 
int a = 3; 

che significa che hai una nuova definizione di una e che causa un errore.

Prima risposta: Per la mia comprensione, questo rompe parti della regola della definizione One. Specificamente, intendo la seguente regola (in riferimento a MISRA C++ 2008) che dice che un identificatore con linkage esterno dovrebbe sempre avere solo una definizione. Nel tuo esempio hai una definizione nel file corrente (auto a = 3;) e con l'esterno fai riferimento anche a una definizione in un altro file.

+6

In questo esempio, la variabile viene definita esattamente una volta. Non c'è violazione di odr a meno che 'auto a' non sia in conflitto con la dichiarazione originale. Extern non deve fare riferimento alla definizione in un altro file. Si riferisce semplicemente a una definizione in * alcuni * file. Va bene definire una variabile nello stesso file in cui è stata dichiarata extern. – user2079303

+0

Questo è vero. Ma quando non esiste una definizione esterna di 'external int a', allora sarebbe la stessa cosa della scrittura: extern int a; int a = 3; il che significa che abbiamo anche due definizioni – cpow

+1

Jamboree ha mostrato l'intero codice del programma nella domanda. C'è solo una definizione di 'a' in essa. Certo, se avessi aggiunto più definizioni collegando questa TU ad altre TU, potresti violare l'ODR, ma non penso che sia di questo che si tratta, visto che non ha nulla a che vedere con 'auto'. –

Problemi correlati