2015-04-07 7 views
12

Il codice:Programma con il costruttore "noexcept" accettato da gcc, rifiutato da clang

struct T { T() {} }; 

struct S 
{ 
    T t; 

    S() noexcept = default; 
}; 

int main() 
{ 
// S s; 
} 

g ++ 4.9.2 accetta questo con errori o avvisi, tuttavia clang 3.6 e 3.7 rapporto per la linea 7:

error: exception specification of explicitly defaulted default constructor does not match the calculated one 

Tuttavia, se la linea S s; non è commentata, g ++ 4.9.2 ora riporta:

noex.cc: In function 'int main()': 
noex.cc:12:7: error: use of deleted function 'S::S()' 
    S s; 
    ^
noex.cc:7:5: note: 'S::S() noexcept' is implicitly deleted because its exception-specification does not match the implicit exception-specification '' 
    S() noexcept = default; 
    ^

Quale compilatore è giusto per il codice originale?


Priorità:

g ++ permette anche il seguente da aggiungere ai main:

std::cout << std::is_constructible<S>::value << '\n'; 

che emette 0. Ho riscontrato questo problema durante l'utilizzo di clang per compilare un codice complicato che ha fatto un uso massiccio di modelli, SFINAE e noxcept. In quel codice S e T sono classi template; quindi il comportamento dipende da quali tipi di S sono stati istanziati con. Clang lo rifiuta con questo errore per alcuni tipi, mentre g ++ lo consente e lo SFINAE funziona basato su is_constructible e tratti simili.

+0

Perché nel costruttore S riceverai una chiamata al costruttore T che potrebbe generare qualche eccezione.Clang ha ragione, credo che –

+1

@SeverinPappadeux sia vero circa le eccezioni ma il problema sembra essere se il codice debba essere immediatamente respinto, o se l'effetto di '= default' dovrebbe essere su * define as deleted * che g ++ sembra fare. –

risposta

15

Dipende dalla versione dello standard che si sta consultando.

N3337 [dcl.fct.def.default]/p2:

Una funzione esplicitamente-default [...] può avere un esplicito specifica delle eccezioni solo se è compatibile (15,4) con la specifica exception sulla dichiarazione implicita.

che rende malformato il codice originale.

questo è stato cambiato da CWG issue 1778 a leggere (N4296 [dcl.fct.def.default]/P3):

Se una funzione che viene esplicitamente in default è dichiarata in un specifica delle eccezioni che non è compatibile (15.4) con la specifica di eccezione sulla dichiarazione implicita, quindi

  • se la funzione è esplicitamente impostata sulla sua prima dichiarazione, viene definita come eliminata;
  • in caso contrario, il programma è mal formato.

che significa che il costruttore ora è semplicemente definito come cancellato. (La suddetta formulazione incorporava le modifiche apportate da N4285, una carta post-C++ 14 che apportava alcune modifiche di pulizia che intendevano essere puramente redazionali.La versione N3936 è sostanzialmente la stessa.)

Presumibilmente GCC implementa la risoluzione di CWG1778, mentre Clang no.

+0

Quale versione è apparsa nel C++ 14 pubblicato? (clang 3.7 continua a rifiutare il codice con -std = C++ 14) –

+0

@MattMcNabb Il problema ha lo stato "C++ 14", quindi la seconda versione dovrebbe essere in C++ 14. Si noti che questo è un DR, quindi probabilmente verrà implementato anche in modalità C++ 11. –

+0

@MattMcNabb 4296 è più o meno quello che è stato votato come un C++ 14 modulo typos e tale –

Problemi correlati