Выравнивание элементов структуры с _Alignas

Меня интересовало следующее: применим ли новый спецификатор выравнивания _Alignas в C11 к членам структуры?

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

Однако мне кажется, что цель стандарта состоит в том, что _Alignas должен применяться к элементам структуры, поскольку параграф на _Alignas (§ 6.7.5) утверждает, что «атрибут выравнивания не должен указываться в объявлении [... ] битовое поле ". Учитывая, что термин «битовое поле» определен в § 6.7.2.1 как член структуры (точная формулировка: «такой член называется битовым полем»), я всегда интерпретировал это предложение неявно означать, что спецификаторы выравнивания были разрешены для членов, не являющихся битовыми полями.

Проверка на соответствие существующим реализациям показывает, что и Clang 3.0, и GCC 4.7 поддерживают _Alignas на членах структуры без жалоб (с -pedantic). Исходный код Clang воспроизводит ту же грамматику из N1570, за исключением того, что Parser::ParseSpecifierQualifierList разрешает спецификаторы выравнивания; однако функция содержит элемент TODO, который гласит:

/// TODO: diagnose attribute-specifiers and alignment-specifiers.

Код синтаксического анализатора GCC C выглядит похожим, то есть даже несмотря на то, что он цитирует стандартную грамматику, он позволяет использовать спецификаторы выравнивания в списках спецификаторов-квалификаторов.

Я также проверил список известных дефектов, а также comp.lang.c и comp.std.c, чтобы увидеть, поднималась ли там эта тема, но, похоже, это не так. Следовательно, мой вопрос: разрешены ли спецификаторы выравнивания для членов структуры?

РЕДАКТИРОВАТЬ: соответствующие правила грамматики:

// Compare this...
(6.7) declaration-specifiers:
           storage-class-specifier declaration-specifiers_opt
           type-specifier declaration-specifiers_opt
           type-qualifier declaration-specifiers_opt
           function-specifier declaration-specifiers_opt
           // This seems to be the only place that mentions
           // alignment-specifier on the rhs of a rule.
           alignment-specifier declaration-specifiers_opt

(6.7.2.1) struct-or-union-specifier:
           struct-or-union identifier_opt { struct-declaration-list }
           struct-or-union identifier

(6.7.2.1) struct-declaration-list:
           struct-declaration
           struct-declaration-list struct-declaration

(6.7.2.1) struct-declaration:
           specifier-qualifier-list struct-declarator-list_opt ;
           static_assert-declaration

// ...to this.
(6.7.2.1) specifier-qualifier-list:
           type-specifier specifier-qualifier-list_opt
           type-qualifier specifier-qualifier-list_opt
           // Missing alignment-specifier specifier-qualifier-list_opt?

(6.7.5) alignment-specifier:
          _Alignas ( type-name )
          _Alignas ( constant-expression )

person rz0    schedule 20.05.2012    source источник


Ответы (1)


Раздел 6.7.5, стр. 6, четко указывает, что это также касается выравнивания элементов.

Требование выравнивания объявленного объекта или члена принимается как указанное выравнивание.

Итак, предполагаемая семантика такова. Если, как вы говорите, формальная спецификация грамматики пропускает этот бит (я не проверял), это дефект, и вы должны сообщить о нем.

Изменить: Глядя на грамматику, мне кажется, что добавление alignment-specifier в 6.7.2.1 отсутствует в случаях specifier-qualifier-list, а также что текстовое объяснение в параграфе 14 было бы в порядке.

person Jens Gustedt    schedule 20.05.2012
comment
Понятно - я пропустил этот бит (или, может быть, перечитал его слишком много раз, чтобы он каким-то образом проскочил, когда я наконец отправил сообщение в SO); Насколько я понимаю, это также должно было применяться к членам. Но потом я начал проверять Clang и GCC и запутался. Если у вас есть время, не могли бы вы также взглянуть на грамматику? Возможно, я тоже что-то пропустил ... (так как я пропустил отрывок, который вы цитируете, что действительно проясняет намерение) Спасибо. - person rz0; 21.05.2012
comment
Так что это было не просто то, что я видел ... Спасибо, что нашли время изучить проблему. Что касается сообщения о дефекте, то AFAIK, стандартный комитет - довольно герметичный орган и немного пугающий для такого случайного парня в Интернете, как я. Но если ошибка реальна, я уверен, что кто-то важный заметит ее рано или поздно, начиная с различных разработчиков. :) (TODO в коде Clang, кажется, указывает на то, что по крайней мере кто-то заметил отсутствие alignment-specifier в specifier-qualifier-list.) - person rz0; 21.05.2012
comment
Похоже, что _Noreturn также должно быть разрешено в specifier-qualifier-list для членов структуры указателя на функцию, потому что это разрешено в обычных объявлениях указателя на функцию (не являющихся членами структуры). - person librik; 13.06.2014