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.
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 than the datatype's natural alignment, while the compiler directive can make it more lenient too.
Aside: On VS2013 alignof
and stdalign.h
are unsupported; although VS2015 supports alignof
and alignas
, it still does not have the header mandated by the C++ standard cstdalign
(or its C counterpart); so availability should be checked manually based on the tool chain version. This is perhaps due to the poor support of the C language by Visual Studio. GCC, OTOH, has all of it; header, macros (__alignas_is_defined
and __alignof_is_defined
) and keywords (alignas
and alignof
).
With these information, we can define something that works and has a common syntax across compilers:
#ifdef _MSC_VER
# if (_MSC_VER >= 1800)
# define __alignas_is_defined 1
# endif
# if (_MSC_VER >= 1900)
# define __alignof_is_defined 1
# endif
#else
# include // __alignas/of_is_defined directly from the implementation
#endif
#ifdef __alignas_is_defined
# define ALIGN(X) alignas(X)
#else
# pragma message("C++11 alignas unsupported :( Falling back to compiler attributes")
# ifdef __GNUG__
# define ALIGN(X) __attribute__ ((aligned(X)))
# elif defined(_MSC_VER)
# define ALIGN(X) __declspec(align(X))
# else
# error Unknown compiler, unknown alignment attribute!
# endif
#endif
#ifdef __alignof_is_defined
# define ALIGNOF(X) alignof(x)
#else
# pragma message("C++11 alignof unsupported :( Falling back to compiler attributes")
# ifdef __GNUG__
# define ALIGNOF(X) __alignof__ (X)
# elif defined(_MSC_VER)
# define ALIGNOF(X) __alignof(X)
# else
# error Unknown compiler, unknown alignment attribute!
# endif
#endif
Example client code using the above
struct ALIGN(32) MyStruct
{
...
};
static_assert(ALIGNOF(MyStruct) == 32, "Error: MyStruct not on a 32-byte boundary!");