Подтвердить что ты не робот

Синтаксические неоднозначности С++

Предположим, что есть объявление:

struct A { static int i; };
A a;

Как я знаю, строка ввода int decltype(a)::i = 0; не имеет строго описанного поведения.

Его можно проанализировать как int decltype(a)::i = 0;, где: int - спецификатор decl и decltype(a)::i declarator.

Однако он может быть проанализирован как int decltype(a) ::i = 0;, где int и decltype(a) анализируются как decl-specifer s, а ::i - это объявление (re) глобальной переменной i - компилятор должен дать сообщение об ошибке msg, которое выглядит как "decl-specifier-seq не должен содержать двух спецификаторов типа.

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

Во всяком случае, в int A::a = 0;, A обязательно анализируется как часть declarator, потому что A является именем типа и, как описано в стандартном

Если имя типа встречается при разборе описания-spec-seq, оно интерпретируется как часть описания-spec-seq тогда и только тогда, когда нет предыдущего спецификатора типа, отличного от cv-квалификатора в Децл-спецификатор-сл.

В constrant decltype(a) не является именем типа, это спецификатор типа.

Я не "ссорился в соломе", у меня есть этот вопрос, потому что я пишу свой синтаксический анализатор для С++.

Итак, интересно, должно ли быть описание:

Если при разборе описания-spec-seq встречается спецификатор типа, он интерпретируется как часть описания-spec-seq тогда и только тогда, когда нет предыдущего спецификатора типа чем cv-определитель в spec-spec-seq.

4b9b3361

Ответ 1

Ваше определение явно запрещено [dcl.meaning]/1:

Вложенное имя-спецификатор квалифицированного идентификатора-декларатора не начинается с спецификатора decltype.

(GCC и VС++ в этом отношении являются ошибками.)

Реализация конкретной диагностики (независимо от того, относятся ли вы к нескольким спецификаторам типов или неверному вложенному имени-спецификатору), является просто проблемой QoI. На самом деле реализации, вероятно, будут реализовывать некоторые вариации принципа максимального кнута для спецификаторов типов, аналогично тому, как оригинальная формулировка вашей цитаты (которая поэтому GCC и VС++ принимают ваш код). Однако ICC дает точное сообщение об ошибке, которое вы ожидали:

ошибка: неверная комбинация спецификаторов типов

Обратите внимание, что ваше "разрешение" также неверно, потому что мы можем иметь несколько спецификаторов типов; см. [dcl.type]/2. Фактически, формулировка в порядке, так как есть, потому что если начало допустимого декларатора (в вашем недопустимом случае, decltype(a)) является спецификатором типа, это также имя типа.