2014-11-05 8 views
7

Niedawno answered a question czynienia z naruszeniem draft C++14 standard: N4140 sekcji 3.3.7Class zakresu ust 1 reguły 2 który mówi:Czy przepis 3 w sekcji 3.3.7/1 z N3936 jest zbędny?

nazwę N stosowany w klasie S odnoszą się do tej samej deklaracji w jego kontekście i kiedy ponownie ocenione w wypełnionym zakresie S. nr diagnostyka jest wymagana w przypadku naruszenia tej zasady.

w regule czasu 3 wydawał również istotne i mówi:

przypadku zmiany kolejności zgłoszeń członków w klasie daje alternatywną ważnego programu podstawie (1) i (2), program jest chory -formułowany, nie wymaga diagnostyki .

Moja pierwsza reakcja jest taka, że ​​zasada 3 wydaje się zbędne i jest naprawdę tylko wyjaśnienie reguły 2 i nie obejmuje żadnych przypadków dotychczas nieuwzględnione. Zmiana kolejności, która skutkuje alternatywnym ważnym programem, również musiałaby naruszać regułę 2.

Czy zasada 3 jest zbędna, czy jest kilka przypadków skrajnych, które wymagają obu reguł?

Odpowiedz

8

Według Defect Report 1875: Reordering declarations in class scope reguły 3 jest zbędny, a proponowane rozwiązanie jest usunąć regułę 3, to mówi:

Potrzeba Zasada # 3 nie jest jasne; wydaje się, że każda inna zmiana kolejności w innym przypadku musiałaby naruszyć zasadę nr 2, aby przyniosła inną interpretację. Podjęta dosłownie reguła # 3 również miałaby zastosowanie do zmiany kolejności niestatycznych elementów danych bez nazwy . Czy można go po prostu usunąć?

a proponowane rozwiązanie jest:

Usuń trzecią pozycję wśród 3.3.7 [basic.scope.class] ustęp 1 i zmienić numerację kolejnych przedmioty

Mimo tej wady Raport zdaje się potwierdzać mój początkowy podejrzany, którym pozostaję z nękającym uczuciem, że być może zasada 3 jest nieco szersza. Sekcja 3.3.7 zawiera następujący przykład:

enum { i = 1 }; 

class X { 
    char v[i]; // error: i refers to ::i 
      // but when reevaluated is X::i 
    int f() { return sizeof(c); } // OK: X::c 
    char c; 
    enum { i = 2 }; 
}; 

który narusza zarówno zasadę 2 i 3 ale mały uszczypnąć:

enum { i = 1 }; 

class X { 
    enum { i = 2 }; 
    char v[i]; // no longer refers to ::i 
       // but reordering can cause it to refer to ::i again 

    int f() { return sizeof(c); } // OK: X::c 
    char c; 
}; 

zdaje się nie naruszać zasadę 2 ale na pewno wydaje się naruszać zasadę 3. Uznałbym, że ten przykład kodu jest kłopotliwy, ponieważ zmiana kolejności członków może z łatwością spowodować, że kod znowu będzie naruszał regułę 2, ale diagnostyka nie jest wymagana, aby wskazać to, co czyni ten kod raczej kruchym.

Aktualizacja

O ile mi zrozumieć wyklucza 3 nie stosuje się do tego przykładu wspomnianego przez Caseya w komentarzu:

class X { int a; int b; }; 

bo chociaż istnieje więcej niż jedna ważna kolejność ta sprawa nie podlega zasadom 1 i 2, które wymagają: 3:

Alternatywny ważny program pod (1) i (2)

+0

Nie zgadzam się z twierdzeniem, że ostatni przykład kodu jest niepożądany. Może nie najlepszy styl, ale pisanie programów w dużych wymaga, aby kod lokalny był w pewnym stopniu izolowany od zmian w pozostałej części programu. Wymaganie, aby ta klasa zadeklarowała 'v' jako' char v [X :: i]; ', aby była dobrze uformowana, wydaje się być uciążliwa. Kiepski styl lub nie, oczywiście nie zgadzam się, że program powinien mieć niezdefiniowane zachowanie ("źle sformułowany, NDR"). – Casey

+0

@Casey Czy zgadzasz się, że pierwszy przypadek jest niepożądany? –

+1

Zgadzam się z tą odpowiedzią. –