2016-03-23 33 views
6

bu kısa parçasını inceleyin katılmıyorum:bir değerle istisna yakalamak - gcc ve clang

main.cpp:17:13: error: no matching constructor for initialization of 'B' 
    catch(B) { 
      ^

Kim haklı: clang onunla kötü şekillendirilmiş dikkate alır

struct B { 
    B() = default; 
    explicit B(B const&) { } 
}; 

struct D : B { }; 

int main() { 
    try { 
     throw D{}; 
    } 
    catch(B) { 
    } 
} 

gcc bu kodu kabul?

+0

Ayrıca, belki her ikisi de doğru .. – xaxxon

+0

@ xaxxon Bunun gibi bir şüphe şüphesiz. Ya geçerli olması gerekiyordu ya da geçersiz olması gerekiyordu. Her iki durumda da istisnalar garip. – Barry

+0

Hmm, GCC, bir "B" atmaya çalışırsanız doğru şekilde reddeder, ancak bir "D" atmaya çalışmadığınız takdirde değil. –

cevap

4

Ben düşünün bu bir gcc hatasıdır (ve hiç kimse bu cevabı henüz reddetmediğinden, 70375 olarak gönderdim).

Her iki derleyiciler doğru D{} sadece BD bir taban sınıfı olduğunu denetler [except.handle]/3, gereği, yakalanmış gerektiğini kabul ediyoruz.

Ancak işleyici başlatma olarak [except.handle]/15 tanımlanır:

T veya evT&, özel nesneden başlatıldı tip ev istisna-beyanı ile beyan değişkeni, E türünde, aşağıdaki gibi:
- T, E taban sınıfı ise, değişken, istisna nesnesinin karşılık gelen taban sınıfı alt nesneden kopya başlangıç ​​durumuna (8.5); B yıllardan itibaren izin alınmalıdır

D __temporary_object{}; 
B __handler = static_cast<B&>(__temporary_object); 

yapıcı explicit işaretlenmiş kopyalama (copy-başlatma sadece kesmek yok): olarak bu başlatma ima

çalışır.

+0

ve örneğinizdeki "açık" ifadesini kaldırmak, clang'ın istisnayı kabul etmesini sağlar. – xaxxon