2015-07-05 9 views
12

Il seguente programma viene compilato senza errori con MSVS, clang e GCC:errore di compilazione quando si definisce una funzione di membro, ma solo nel GCC

class A; 

namespace Y { 
    using ::A; 
    class A {}; 
} 

int main() {} 

Ora definiamo una funzione membro. Ora si compila ancora con MSVS e clang, ma non con GCC:

class A; 

namespace Y { 
    using ::A; 
    class A { void f() {} }; 
} 

int main() {} 

GCC fornisce il seguente messaggio di errore:

  • prog.cc:5:22: errore: definizione di 'vuoto A: : f() 'non è nel namespace che racchiude' A '[-fermermissivo]

Perché è così? È un bug in GCC?

Se la seconda versione del programma viola una regola dello standard C++, quale regola viola e perché MSVS e clang non danno un messaggio diagnostico per quella violazione?

Si tratta di un caso di ambiguità dello standard C++?

Dal messaggio di errore sembra GCC pensa erroneamente abbiamo una violazione della seguente regola:

  • http://eel.is/c++draft/class.mfct#2 "Una definizione di funzione membro che appare al di fuori della definizione della classe deve figurare in un ambito spazio dei nomi che racchiude la definizione della classe. "

Non abbiamo una violazione di questa regola poiché la definizione della funzione membro si trova all'interno della definizione della classe. La mia teoria è che GCC confonde la dichiarazione di classe A; nel namespace globale con la classe di definizione di classe A {...} nel namespace Y. Penso che abbiamo un bug in GCC.

Con GCC dichiarano la stessa entità. Questo può essere visto osservando che nella prima versione del programma è possibile usare :: A come tipo completo in main quando si compila con GCC. Lo stesso per MSVS. Con Clang, tuttavia, dichiarano entità diverse. Questa differenza potrebbe essere dovuta ad un'ambiguità nello standard C++. Indipendentemente da tale ambiguità, chiaramente non stiamo violando lo http://eel.is/c++draft/class.mfct#2. Questa regola è molto chiara.

questione connessa: Class declaration in same scope as using declaration compiles in GCC but not MSVS

+1

Dobbiamo indovinare qual è il messaggio di errore? –

+0

Ho modificato la domanda per includere il messaggio di errore. L'ho eseguito qui: http: // melpon.org/wandbox/permlink/W3284yJiSuXuahQu – Supremum

+0

Personalmente, a me sembra che il codice sia errato - si inoltra dichiarare "A" al di fuori della classe, quindi definirlo nella classe; senza l'istruzione using, quelle sarebbero due classi separate (es. 'classe A' e' classe Y :: A', ma con l'istruzione using, hai già un nome 'A' nell'ambito di' classe Y', quindi la successiva definizione di una 'classe A' in quell'ambito sembra che dovrebbe nascondere il nome importato (e quindi compilare) _o essere preso come definizione per esso, nel qual caso è una violazione di quella regola che hai postato (beh, almeno _if_ rimuovi la parola "funzione"). – celticminstrel

risposta

4

Entrambi questi programmi sono mal formata secondo lo standard C++. Ciò è dovuto lo stesso motivo come nella relativa domanda:

Class declaration in same scope as using declaration compiles in GCC but not MSVS

tutti i compilatori dovrebbero dare un errore di compilazione in entrambi i casi: Quindi, questo indica un bug in MSVS, clang e GCC.

Il bug in clang è stato confermato e fissato: https://llvm.org/bugs/show_bug.cgi?id=24030

La ragione per cui GCC dà un messaggio di errore strano per il secondo programma è che si confonde quando non è riuscito a rilevare l'errore che è presente sia nella primo e secondo programma.