C宏的标准符合性

dea*_*ndi 8 c c++

我在这里有这个小宝石(从C-FAQ中偷偷窃取的想法):

/* A lot of checks omitted to get rid of the architectures with a "weird" endianness */
/*...*/
#define MP_ENDIANESS ( (0x41424344ul == *(uint32_t*)"ABCD") ? MP_BIG_ENDIAN : MP_LITTLE_ENDIAN )
Run Code Online (Sandbox Code Playgroud)

它是否符合新的当前标准(在提出此问题时为C-18)(不是不确定的行为),并且如果是,则哪个较老的标准也支持它?

它也是符合标准的C ++吗?(是的,我知道std::endian

PSk*_*cik 10

它有几个问题:

  • uint32_t 不保证存在
  • "ABCD",衰减为char*(C)/ char const*(C ++)的数组,不能保证适当地对齐uint32_t*。如果不是,则演员为UB
  • 如果进行了强制转换,则deref(*(uint32_t*)"ABCD")是严格的别名冲突(UB)

您可能想简单地执行以下操作:

#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
Run Code Online (Sandbox Code Playgroud)

(之所以char可行,是因为它将存在,可以别名任何东西,并且具有最低的对齐要求。)

所有宏(包括您的尝试)都具有以下缺点:不适用于预处理器条件(#if ...)或需要整数常量表达式(case标签,数组大小,位字段大小)的上下文,但是当在其他地方使用时,现代编译器通常会处理就优化的程序集输出而言,其结果是编译时间常数。