2015-07-05 33 views
12

aşağıdaki programı MSVS, clang ve GCC ile hatasız derlediğinde:Derleme hatası üye işlevi tanımlayarak, fakat sadece GCC

class A; 

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

int main() {} 

Şimdi üye işlev tanımlayalım. Şimdi yine GCC ile MSVS ve clang derler ama değil:

class A; 

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

int main() {} 

GCC aşağıdaki hata iletisini verir:

  • prog.cc:5:22: hatası: 'boşluk A'nın tanımı: : f() ',' A '(f)' i içermeyen bir ad alanında yer almaz.

Neden? Bu GCC'de bir hata mı?

Programın ikinci sürümü, C++ standardının bir kuralını ihlal ediyorsa, hangi kural ihlal edilir ve neden bu ihlal için MSVS ve clang bir tanı mesajı verir?

Bu, C++ standardında bir belirsizlik durumu mu?

  • http://eel.is/c++draft/class.mfct#2 "Bir üye işlev tanımı sınıf tanımının dışında görünen kapatan bir ad kapsamında yer almalıdır: o GCC hatalı aşağıdaki kural ihlali olduğunu düşünen benziyor hata mesajı itibaren

    sınıf tanımı.

Üye işlev tanımı, sınıf tanımının içinde bulunduğundan, bu kuralın ihlali yoktur. Benim teorim GCC'nin deklarasyon sınıfı A ile karıştırdığı; A adındaki A {...} sınıf tanımı sınıfı ile global ad alanında, GCC'de bir hata olduğunu düşünüyorum.

GCC ile aynı varlığı beyan ederler. Bu, programın ilk versiyonunda, GCC ile derleme sırasında ana bir tam tip olarak kullanılmasının mümkün olduğunu gözlemleyerek görülebilir. MSVS için aynı. Ancak Clang ile farklı varlıklar ilan ederler. Bu fark, C++ standardındaki bir belirsizlik nedeniyle olabilir. Böyle bir belirsizlikten bağımsız olarak, http://eel.is/c++draft/class.mfct#2'u ihlal etmeyiz. Bu kural çok açık.

İlgili soru: Bu programların Class declaration in same scope as using declaration compiles in GCC but not MSVS

+1

Hata mesajının ne olduğunu tahmin etmemiz gerekiyor mu? –

+0

Sorunu, hata mesajını içerecek şekilde düzenledim. Ben burada koştum: http: // melpon.org/wandbox/permlink/W3284yJiSuXuahQu – Supremum

+0

Şahsen bana göre, bu kod yanlış görünüyor - sınıfın dışında “A” ifadesini ileri götürüyorsunuz, sonra sınıfta tanımlayın; kullanma deyimi olmaksızın, bunlar iki ayrı sınıf (yani "sınıf A" ve "sınıf Y :: A" olacaktır, ancak kullanma ifadesiyle, zaten "Y" sınıfının "Y" adı altında bir adınız vardır. Bu kapsamda bir "A sınıfı" nın sonraki tanımı, içe aktarılan adın (ve dolayısıyla derlenmesinin) _or_ için bir tanım olarak saklanması gerektiği gibi görünür; bu durumda, yayınladığınız kuralın ihlalidir. en az _if_ "function" kelimesini kaldırırsınız. – celticminstrel

cevap

4

Hem kötü oluşmuş C++ standardına göre vardır.

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

Tüm derleyiciler her iki durumda da bir derleme hatası vermelidir: Bunun nedeni, ilgili söz konusu aynı nedenden biridir Yani bu MSVS, clang ve GCC bir hata olduğunu gösterir.

clang bulunan böcek doğruladı ve düzeltildi: https://llvm.org/bugs/show_bug.cgi?id=24030

GCC ikinci program için garip bir hata mesajı verir nedeni hem de mevcut olduğu hatayı tespit etmek için başarısız olunca o kafası karışıyor olmasıdır İlk ve ikinci program.