Все кредиты go @ ens c потому что 1) его ответ правильный и 2) он направил меня на правильный путь в отношении документации.
Однако в цитированных им цитатах говорится, что атрибут не применяется ко всему объявлению, а только к соответствующему декларатору. Затем он привел несколько примеров, в которых атрибут применялся ко всему объявлению.
Сначала я не понимал, почему и когда это так, но теперь нашел соответствующее утверждение в документации. Его трудно найти, потому что абзац, в котором он находится, длинный и содержит много отвлекающей дополнительной информации.
Обратите внимание на раздел «Все остальные атрибуты» на этой странице G CC документация. Он содержит следующий абзац (сокращенный и выделенный мной):
Любой список спецификаторов и квалификаторов в начале объявления может содержать спецификаторы атрибутов, независимо от того, есть ли такой список может в этом контексте содержать спецификаторы класса хранения. [...] Все спецификаторы атрибутов в этом месте относятся к объявлению в целом. [...]
Объединение приведенной выше цитаты и цитат из @ens c, ситуация на удивление проста:
Если __attribute__
появляется в начале объявления, это относится ко всему объявлению, то есть ко всем деклараторы / объявленные объекты.
Во всех остальных случаях он применяется только к определенному c декларатору, в котором он находится, то есть только к соответствующему идентификатору или объекту.
Единственное, что может ввести в заблуждение в приведенной выше цитате, - это термин «начало объявления». В руководстве G CC не объясняется, что именно начинается с объявления.
Возможно, этот термин заимствован из одной из многих C и связанных спецификаций, но я не нашел краткого определения пока.
По результатам тестирования в
__attribute__((aligned(16))) unsigned char a,
b;
и
unsigned char __attribute__((aligned(16))) a,
b;
атрибут считается частью списка спецификаторов и квалификаторов в начале декларации.
Напротив, в
unsigned char a __attribute__((aligned(16))),
b;
атрибут, очевидно (согласно результатам тестирования) не , считается частью списка спецификаторов и квалификаторы в начале объявления.
Для меня, как говорящего на английском sh, это очень беспокоит:
Я бы рассмотрел первую строку в каждом из примеров выше, чтобы быть началом объявления. Примечательно, что я бы считал список спецификаторов и квалификаторов в первой строке третьего примера частью начала объявления, хотя этот список (в данном случае состоящий только из части __attribute__
) идет после идентификатора название. Очевидно, я был бы неправ, делая это.
Пожалуйста, не воспринимайте это как дополнительный вопрос - это скорее дополнительный аспект в этом ответе. Возможно, люди GNU однажды прочтут это и прояснят документы: -)