Обоснование нерегулярности синтаксиса атомарного спецификатора-vs-квалификатора C11?


Здесь есть связанный вопрос "что": грамматическая неоднозначность C11 между спецификатором _Atomic type и квалификатором

Что меня интересует, так это Почему, поскольку обоснование C11 еще не опубликовано, и это кажется излишне сложным.

Грамматика включает в себя оба из них (и разрешает неоднозначность в пользу shifting (, а не reduce (который в противном случае был бы в lookahead, если бы за ним следовал declarator или abstract-declarator), достижимый из declaration-specifiers или specifier-qualifier-list:

atomic-type-specifier: _Atomic ( type-name )
type-qualifier: _Atomic
Это приводит к следующему коду:
int i1;
int (i2); // valid, same as i1 - usually seen in the context of pointer-to-function or pointer-to-array
int _Atomic a1;
int _Atomic (a2); // invalid
_Atomic (int) a3; // valid, same as a1

Мысли:

  • _Atomic не следует изменять массив или функцию. За исключением избыточных скобок вокруг Декларатора, это означает, что он будет действителен для #define _Atomic(x) x _Atomic (если бы это было законно для ключевых слов #define, конечно).

  • Когда это происходит как qualifier, _Atomic это та же синтаксическая часть, что и const, А C-программисты уже привыкли ставить const на правильную сторону, так что это не может быть для "удобства использования".

1 3

1 ответ:

Обоснование находится в N1485 :

Ключевое слово _Atomic также может быть использовано в виде _Atomic(T), где T - тип, в качестве спецификатора типа эквивалентный _Atomic T. Таким образом, _Atomic(T) x, y; объявляет x и y с одинаковым типом, даже если T - тип указателя. Это позволяет банальной совместимости с++0х только с определением макроса _Atomic(T) на языке C++ как atomic<T>.