Ниже приведен неверный код:
int i = 0, double j = 2.0;
В проекте стандарта говорится, почему:
[N4140/7.1.6]
2
Как правило, не более одного типа-спецификатора допускается в полный decl-specifier-seq декларации или в type-specifier-seq или trailing-type-specifier-seq. Единственными исключениями из этого правила являются следующие:-
const
можно комбинировать с любым спецификатором типа, кроме самого себя.-
volatile
можно комбинировать с любым спецификатором типа, кроме самого себя.-
signed
илиunsigned
можно комбинировать сchar
,long
,short
, илиint
.-
short
илиlong
можно комбинировать сint
.-
long
можно комбинировать сdouble
.-
long
можно комбинировать сlong
.
Да, это предотвращает что-то глупое как int int
, но я не вижу ничего плохого в неверном коде, опубликованном выше. Цитируя [N4140/7]
, простая декларация состоит из объявления decl-specifier-seq opt init-declarator-list opt;
[N4140/8]
показывает, что список init-declarator состоит из init-declarator-list, init-declarator,
а init-declarator - инициализатор декларатора opt.
Поскольку мы имеем дело только с синтаксисом формы int i = 0
, то мы должны заботиться о деклараторе ptr-declarator, который является noptr-декларатором, который является атрибутом-атрибутом declarator-id-seq opt, и, наконец, идентификатор declarator состоит только из ...
opt id-expression.
Для полноты, [N4140/5.1.1]
говорит, что id-выражение может быть неквалифицированным-id или просто идентификатором.
Если я пока не споткнулся, это то, что отражает грамматика.
int
decl-specifier-seq
i
unqualified-id
= 0
инициализатор
int i = 0
init-declarator
Так как простая декларация имеет spec-specifier-seq, только один spec-specifier-seq применяется ко всему списку init-declarator-list.
Как ни странно, это означает, что вы не можете сделать что-то вроде этого:
int i, const j;
Тем не менее:
int i, * j;
совершенно законно, потому что звезда является частью ptr-оператора. Но вы не можете этого сделать:
int i, const * j; // pointer to const int
Это означает, что в следующем коде i
становится указателем на const int. Сюрприз!
int h = 25;
int const * j, * i = &h;
*i = 50; // error: assignment of read-only location '* i'
В [N4140/8]
подразумевается намерение:
3
Каждый декларатор init в декларации анализируется отдельно как если он был в декларации сам по себе. 9999) Декларация с несколькими деклараторами обычно эквивалентна соответствующая последовательность объявлений, каждая с одной описатель. Это
T D1, D2, ... Dn;
обычно эквивалентен
T D1; T D2; ... T Dn;
Вопрос в том, почему это так?
Если это было законно, вы могли бы сделать это для циклов, что несколько полезно.