'Cross-platform ALIGN(x) macro?

I would like to create a struct that has a certain alignment.

I would like to use the same struct definition for both GCC and VisualC++ compilers.

In VisualC++, one typically does this:

__declspec(align(32))
struct MyStruct
{
// ...
};

In GCC, one typically does this:

struct MyStruct
{
// ...
} __attribute__ ((aligned (32)));

I could of course create the appropriate macros to make this work:

BEGIN_ALIGNED_STRUCT(32)
struct
{
// ...
}
END_ALIGNED_STRUCT(32)
;

And thus be able to handle both cases transparently, but here I have to duplicate the alignment constant (32), which I'd like to avoid.

An alternative in GCC is to put the __attribute__ after the struct tag, as mentioned in the docs, like so:

struct __attribute__ ((aligned (32))) MyStruct
{
// ...
};

And thus I could make this type of syntax work:

ALIGNED_STRUCT(32) MyStruct
{
// ...
};

Does anyone have any better versions? Other ideas? I tried a little code searching, but didn't find anything too promising.


Update: Based on @John's comment, here's another version that could work (I haven't compiled it, but the docs indicate it's an OK idea)

struct MyStruct_Unaligned
{
// ...
};

TYPEDEF_ALIGNED(32, MyStruct_Unaligned, MyStruct);

// Would expand to one of:
// 
// typedef __declspec(align(32)) MyStruct_Unaligned MyStruct;
//
// typedef struct __attribute__ ((aligned (32))) MyStruct_Unaligned MyStruct


Solution 1:[1]

On Modern Compilers

The new versions of GCC (4.8.1) and VC++ (VS2013) supports the common syntax of having the attribute between struct and the identifier name. This is perhaps due to the new C++11 standard's introduction of the alignas keyword to do the same job the compilers' alignment attribute does; however, alignas can only make the alignment more stricter (wider) than the datatype's natural alignment, while the compiler directive can make it more lenient too. This is the reason I prefer compiler attributes over C++11-introduced alignas specifier (or alignof operator).

We can define something that works and has a common syntax across compilers:

#if defined(__GNUC__) || defined(__clang__)
#  define ALIGN(x) __attribute__ ((aligned(x)))
#elif defined(_MSC_VER)
#  define ALIGN(x) __declspec(align(x))
#else
#  error "Unknown compiler; can't define ALIGN"
#endif

#if defined(__GNUC__) || defined(__clang__)
#    define ALIGNOF(X) __alignof__(X)
#elif defined(_MSC_VER)
#    define ALIGNOF(X) __alignof(X)
#else
#  error "Unknown compiler; can't define ALIGNOF"
#endif

Example client code using the above

struct ALIGN(32) MyStruct
{
    ...
};

static_assert(ALIGNOF(MyStruct) == 32, "Error: MyStruct not on a 32-byte boundary!");

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1