zwol zwol - 3 years ago 265
C Question

Applying alignas() to an entire struct in C

I expected it to be possible to apply alignas/_Alignas to an entire struct declaration, like this:

#include <stddef.h>
#include <stdalign.h>

struct alignas(max_align_t) S {
int field;

struct S s = { 0 };

but both gcc and clang reject the declaration:

(gcc 6.3)

test.c:4:8: error: expected ā€˜{ā€™ before ā€˜_Alignasā€™
struct alignas(max_align_t) S {

(clang 3.8)

test.c:4:1: error: declaration of anonymous struct must be a definition
struct alignas(max_align_t) S {

What gives? Note that both compilers accept this construct if I compile the file as C++, or if
is replaced with the equivalent GCC extension,

struct __attribute__((aligned(__alignof__(max_align_t)))) S {
int field;

Also note that the other plausible placements of

alignas(max_align_t) struct S { ... };
struct S alignas(max_align_t) { ... };
struct S { ... } alignas(max_align_t);

also throw syntax errors (albeit different ones).

Answer Source

C11 is not very clear on these things, but a consensus has emerged how this is to be interpreted. C17 will have some of this clarified. The idea of not allowing types to be aligned is that there should never be different alignment requirements for compatible types between compilation units. If you want to force the alignment of a struct type, you'd have to impose an alignment on the first member. By that you'd create an incompatible type.

The start of the "Constraint" section as voted by the committee reads:

An alignment specifier shall appear only in the declaration specifiers of a declaration, or in the specifier-qualifier list of a member declaration, or in the type name of a compound literal. An alignment specifier shall not be used in conjunction with either of the storage-class specifiers typedef or register, nor in a declaration of a function or bit-field.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download