Standard compliance of a C macro
It has several issues:
uint32_t
isn't guaranteed to exist"ABCD"
, an array decaying to achar*
(C) /char const*
(C++), is not guaranteed to be suitably aligned foruint32_t*
. If it isn't, the cast is UB- if the cast went through, the deref (
*(uint32_t*)"ABCD"
) is a strict aliasing violation (UB)
You might want to simply do something like this instead:
#if !__cplusplus
#define LITTLE_ENDIAN_EH() (*(char*)&(int){1});
#else
//C++ doesn't have compound literals
static int const LITTLE_ENDIAN_EH_ = 1;
#define LITTLE_ENDIAN_EH() (*(char*)&LITTLE_ENDIAN_EH_)
#endif
(Works because char
will exist, can alias anything, and has minimal alignment requirements.)
All the macros, including your attempts, have the disadvantage of being unsuitable for preprocessor conditionals (#if ...
) or in contexts where an integer constant expression is required (case
labels, array sizes, bitfield sizes), but when used elsewhere, modern compilers will generally treat the result as a compile time constant as far as optimized assembly output is concerned.
This is not defined behavior in C++. *(uint32_t*)"ABCD"
treats the memory of "ABCD"
as if it were an uint32_t
, but since it isn't really, this is a strict aliasing violation and undefined behavior.