Standard compliance of a C macro

It has several issues:

  • uint32_t isn't guaranteed to exist
  • "ABCD", an array decaying to a char* (C) /char const* (C++), is not guaranteed to be suitably aligned for uint32_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.

Tags:

C++

C