Синтаксические неоднозначности С++
Предположим, что есть объявление:
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.
Ответы
Ответ 1
Ваше определение явно запрещено [dcl.meaning]/1:
Вложенное имя-спецификатор квалифицированного идентификатора-декларатора не начинается с спецификатора decltype.
(GCC и VС++ в этом отношении являются ошибками.)
Реализация конкретной диагностики (независимо от того, относятся ли вы к нескольким спецификаторам типов или неверному вложенному имени-спецификатору), является просто проблемой QoI. На самом деле реализации, вероятно, будут реализовывать некоторые вариации принципа максимального кнута для спецификаторов типов, аналогично тому, как оригинальная формулировка вашей цитаты (которая поэтому GCC и VС++ принимают ваш код). Однако ICC дает точное сообщение об ошибке, которое вы ожидали:
ошибка: неверная комбинация спецификаторов типов
Обратите внимание, что ваше "разрешение" также неверно, потому что мы можем иметь несколько спецификаторов типов; см. [dcl.type]/2. Фактически, формулировка в порядке, так как есть, потому что если начало допустимого декларатора (в вашем недопустимом случае, decltype(a)
) является спецификатором типа, это также имя типа.