2012-05-24 15 views
9

Supponiamo che io sono:Qual è la specifica di eccezione per un distruttore virtuale predefinito in C++ 11?

class Foo 
{ 
public: 
    virtual ~Foo()=default; 
}; 

Qual è la specifica delle eccezioni sul distruttore in default? È il distruttore in default pari a:

virtual ~Foo() {}; 
or 
    virtual ~Foo() throw() {}; 
or 
    virtual ~Foo() noexcept {}; 

Sezione 15.4 dello standard C++ 11 dice che dipende dalle specifiche di eccezione delle funzioni direttamente invocate dai definizione implicita del distruttore. In questo caso non ci sono membri e non ci sono classi base, quindi AFAIK non ci sono funzioni invocate direttamente dal distruttore implicito. Questa è un'ambiguità (o omissione) nello standard?

Importa, ovviamente, perché se implicitamente ha throw(), tutte le sottoclassi devono dichiarare i loro distruttori con throw(). Non dirmi che è una cattiva idea gettare eccezioni nei distruttori, lo so. Mi occupo di un sacco di codice legacy in cui le specifiche delle eccezioni non sono state usate affatto.

Come punto di informazioni, quando ho provato:

class SubFoo : public Foo 
{ 
public: 
    virtual ~SubFoo(); 
}; 

ho ottenuto un errore (spec eccezione non corrispondenti) in GCC 4.4 (anche se ammetto io non ho avuto passa la linea di comando a destra), ma non in XCode 4.3 usando i compilatori "11".

risposta

4

Eseguire il backup in precedenza nella stessa frase (§15.4/14):

... la sua implicita specifica delle eccezioni specifica il tipo-id T se e solo se T è consentito dal eccezione- specificazione di una funzione direttamente invocata da definizione implicita di f; ..."

Pertanto, se ~Foo non invoca alcuna funzione, ha una dichiarazione implicita che non ammette eccezioni a essere gettati

Secondo.a §15.4/3:

Due eccezioni specifiche sono compatibili se:

  • entrambi sono non-lancio (vedi sotto), a prescindere dalla loro forma,

Ecco il caso qui, quindi non importa se la dichiarazione è throw() o noexcept - i due sono comunque compatibili.

+0

Grazie per la risposta. Per seguire un po 'di più, la specifica dice "Una dichiarazione di un distruttore che non ha una specifica di eccezione è implicitamente considerata avere la stessa specifica di eccezione di una dichiarazione implicita" Quindi "virtual ~ SubFoo();" (senza un'eccezione spec) non è mal formata, a meno che non invochi direttamente funzioni che implicitamente o esplicitamente permettono di lanciare? – user1414050

+0

@ user1414050: Credo che sia corretto, sì - ma noi " rientrando in angoli abbastanza oscuri del linguaggio che non avrei scommesso molto sulla maggior parte dei compilatori per farlo nel modo giusto. In particolare, sospetto che molti (la maggior parte?) compilatori trattino 'virtual ~ SubFoo();' come significato "può lanciare qualsiasi cosa ", proprio come farebbe con una funzione normale. –

+0

Penso che questa conclusione non regge, dal momento che il" se e solo se "è contraddetto dalla seguente frase-frase su allowin tutte le eccezioni (ad esempio, lo standard è auto-contraddittorio qui). E penso che sia discutibile se l'intenzione è che i distruttori non abbiano il lancio di default. Perché sarebbe incompatibile con C++ 03. –

2

Lo standardese inizia bene in C++ 11 §8.4.2/2,

Se una funzione è esplicitamente default sul proprio prima dichiarazione,
- è implicitamente considerato constexpr se la dichiarazione implicita sarebbe,
- è implicitamente considerata la stessa specifica di eccezione come se fosse stata implicitamente dichiarata (15.4), & hellip;

Ma poi, su C++ 11 §15.4/14, la logica devolve rapidamente,

Un implicitamente dichiarata funzione membro speciale (clausola 12) ha la specifica delle eccezioni. Se f è un costruttore predefinito implicitamente dichiarato, costruttore di copia, costruttore di movimento, distruttore, operatore di assegnazione di copia o operatore di spostamento, la sua specifica di eccezione implicita specifica l'ID di tipo T se e solo se lo standard di eccezione è T di una funzione invocata direttamente dalla definizione implicita di f; f deve consentire tutte le eccezioni se qualsiasi funzione invoca direttamente consente tutte le eccezioni e f non deve consentire eccezioni se ogni funzione invocata direttamente non consente eccezioni.

Nel significato standard di "consentire" si tratta esplicitamente di consentire, attraverso una specifica di eccezione.

Se f chiama due funzioni, una delle che specifica e consente quindi T, e uno dei quali consente tutte le eccezioni, quindi f devono entrambi specificare Te consentire tutte le eccezioni che isn t ’ possibile.

Quindi questo sicuramente sembra un difetto nello standard.

Ho trovato un rapporto sui difetti correlato, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1351.

Tuttavia, sembra che questa zona sia solo un grande pasticcio. :-(

+0

@anime downvoter: per favore spiega il tuo downvote in modo che altri possano imparare dalle tue intuizioni. –

+0

Non sembra un DR per me; significa solo che devi considerare che la specifica dell'eccezione specifica T come un sottoinsieme di "consenti tutte le eccezioni". – MSalters

+0

@MSalters: non c'è sintassi per questo? –

Problemi correlati