I'd like to understand the validity of different alignas
specifier position within a plain array definition:
constexpr std::size_t Required=16;
alignas(Required) int iarr1[10]; // 1
int alignas(Required) iarr2[10]; // 2
int iarr3 alignas(Required) [10]; // 3
int iarr4 [10] alignas(Required); // 4
2 is ignored by gcc with a warning.
2 and 4 give plain errors with clang LIVE.
This answer explains why 1 is correct, but does not cover the other cases and I'd like to understand what other forms might be valid.
According to me:
alignas
will be parsed as part of the type (int
) declaration and it cannot apply to types as clang and gcc report (thus, acceptance by msvc would be a bug).int
is forming de decl-specifier-seq while iarr3 alignas(Required) [10]
seems a valid noptr-declarator consisting of a noptr-declarator+attribute-specifier which itself is a noptr-declarator followed by []
forming again a noptr-declarator which, ultimately can be interpreted as an * init-declarator-list*.[]
and the attribute-specifier still form a noptr-declarator); yet it is rejected by clang.What analyses are (in)correct and why?
For the record, the running snippet linked above:
#include <iostream>
int main() {
constexpr std::size_t Required = 16;
alignas(Required) int iarr1[10];
#if defined(__GNUG__)
int iarr2[10];
#if defined(__clang__)
std::cout << "clang rejects int alignas(Required) iarr2[10];\n";
#else
std::cout << "gcc ignore int alignas(Required) iarr2[10]; with warning\n";
#endif
#else
int alignas(Required) iarr2[10];
#endif
int iarr3 alignas(Required)[10];
#ifndef __clang__
int iarr4[10] alignas(Required);
#else
std::cout << "clang rejects int iarr4[10] alignas(Required);\n";
int iarr4[10];
#endif
std::cout << iarr1 << '\n';
std::cout << iarr2 << '\n';
std::cout << iarr3 << '\n';
std::cout << iarr4 << '\n';
}
alignas
can only be applied to variables, non-static data members, and classes ([dcl.align]/1, [dcl.attr.grammar]/5).
In the example you give:
iarr1
([dcl.pre]/4),int
([dcl.spec.general]/1),iarr3
([dcl.meaning.general]/1),int[10]
([dcl.array]/3).Thus, 1 and 3 are well-formed, while 2 and 4 are ill-formed.