Правило 3 в разделе 3.3.7/1 от N3936 лишними?

недавно ответ на вопрос дело с нарушением проект стандарта C++14: N4140 раздел 3.3.7 объем класс абзац 1 правила 2 Он говорит:

имя N, используемое в классе S, должно ссылаться на то же объявление в его контекст и при повторной оценке в завершенной области S. No диагностика необходима для нарушения этого правила.

в то время правило 3 также показалось уместным, и он говорит:

если переупорядочение объявлений членов в классе дает альтернативный допустимый программа под (1) и (2), программа неправильно сформирована, никакая диагностика требуемый.

моя первоначальная реакция-это правило 3 кажется избыточным и на самом деле просто уточнение правила 2 и не охватывает случаи, которые еще не охвачены. Переупорядочение, которое приводит к альтернативной допустимой программе, также должно нарушать правило 2.

таково правило 3 избыточный или есть некоторые крайние случаи, которые требуют обоих правил?

1 ответов


по данным отчет о дефектах 1875: переупорядочивание объявлений в области классов правила 3 избыточна и предложенное решение удалить правило 3 Он говорит:

необходимость правила №3 не ясна; казалось бы, что-либо в противном случае-действительное переупорядочение должно было бы нарушить правило №2, чтобы дайте другую интерпретацию. В буквальном смысле, правило №3 также применить к просто переупорядочению нестатических элементов данных без имени зависимости вообще. Можно ли его просто удалить?

и предлагаемое решение:

исключить третий пункт пункта 3.3.7 [basic.масштаб.класс] пункт 1 и перенумеровать следующие элементы

хотя этот отчет о дефекте, кажется, подтверждает мои первоначальные подозрения, я остался с ноющим чувством, что, возможно, правило 3 - немного шире в конце концов. Раздел 3.3.7 включает следующие пример:

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 };
};

что нарушает как правила 2 и 3 но небольшая настройка:

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;
};

кажется, больше не нарушать правила 2 но, похоже, нарушает правило 3. Я бы счел этот пример кода хлопотным, так как переупорядочение членов может легко привести к тому, что код вернется в нарушение правила 2, но никакая диагностика не требуется, чтобы указать это, что делает этот код скорее хрупкий.

обновление

насколько я понимаю правила 3 не относится к этому примеру, упомянутому Кейси в комментарии:

class X { int a; int b; };

потому что, хотя существует более одного действительного заказа, этот случай не подпадает под оба правила 1 и 2 правила 3 требуется:

альтернативные программы под (1) и (2)