'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 |
