使用c++ 11在编译时以编程方式查找端序

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

本文关键字:方式 编程 查找 c++ 编译 使用      更新时间:2023-10-16

我在SO中提到了很多关于这个话题的问题,但到目前为止还没有找到任何解决方案。这里提到了一个自然的解决方案:在编译时确定端序。
然而,评论中提到的相关问题&同样的答案

经过一些修改,我能够用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");

演示。

这可以被认为是确定词尾的确定性方法吗?还是它错过了类型双关语或其他什么?

自c++ 20以来,您可以使用<type_traits>头中的std::endian:

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

看直播

您的尝试与这个明显不工作的尝试没有什么不同(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,因此此检查不能在编译时执行。