使用 C++11 在编译时以编程方式查找字节顺序

Finding endian-ness programmatically at compile-time using C++11

我在 SO 中提到了很多关于这个主题的问题,但到目前为止找不到任何解决方案。这里提到了一种自然的解决方案:Determining endianness at compile time.
但是,评论中提到的相关问题&相同的答案。

通过一些修改,我可以在没有任何警告的情况下使用 g++ 和 clang++ (-std=c++11) 编译类似的解决方案。

static_assert(sizeof(char) == 1, "sizeof(char) != 1");
union U1
{
  int i;
  char c[sizeof(int)];
};  
union U2
{ 
  char c[sizeof(int)];
  int i;
};  

constexpr U1 u1 = {1};
constexpr U2 u2 = {{1}};
constexpr bool IsLittleEndian ()
{ 
  return u1.i == u2.c[0];  // ignore different type comparison
}   

static_assert(IsLittleEndian(), "The machine is BIG endian");

Demo.

这是否可以被视为确定字节顺序的确定性方法,或者它是否遗漏了类型双关语或其他内容?

您的尝试与这个明显无效的尝试没有什么不同(其中 IsLittleEndian()true 相同):

constexpr char c[sizeof(int)] = {1};
constexpr int i = {1};
constexpr bool IsLittleEndian ()
{ 
  return i == c[0];  // ignore different type comparison
}   

static_assert(IsLittleEndian(), "The machine is BIG endian");

我相信 C++11 不提供在编译时以编程方式确定目标平台字节顺序的方法。我的论点是,在运行时 期间执行该检查的唯一有效方法 是使用 unsigned char 指针检查 int 变量(因为其他类型双关方式不可避免包含未定义的行为):

const uint32_t i = 0xffff0000;

bool isLittleEndian() {
    return 0 == *reinterpret_cast<const unsigned char*>(&i);
}

C++11 不允许创建此函数constexpr,因此无法在编译时执行此检查。

从 C++20 开始,您可以使用 <type_traits> header:

中的 std::endian
#include <type_traits>

int main()
{
    static_assert(std::endian::native==std::endian::big,
                  "Not a big endian platform!");
}

See it live