13

在寻找一种在编译时检查字节顺序的方法后,我提出了以下解决方案:

static const int a{1};

constexpr bool is_big_endian()
{
    return *((char*)&(a)) == 1;
}

GCC 仅在需要 constexpr 的某些情况下接受此代码:

int b[is_big_endian() ? 12 : 25]; //works
std::array<int, testendian() ? 12 : 25> c;  //fails

对于第二种情况,GCC 说error: accessing value of ‘a’ through a ‘char’ glvalue in a constant expression. 我在标准中找不到任何禁止此类事情的内容。也许有人可以澄清在哪种情况下GCC是正确的?

4

3 回答 3

10

这是我从 Clang 3.1 ToT 得到的:

错误:constexpr 函数从不产生常量表达式

§5.19 [expr.const]

p1 某些上下文需要满足本子条款中详述的附加要求的表达式;其他上下文具有不同的语义,具体取决于表达式是否满足这些要求。满足这些要求的表达式称为常量表达式

p2条件表达式是一个核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式:

  • [...]
  • 一个reinterpret_cast(5.2.10);

因此,(char*)&(a)评估为 a reinterpret_cast,因此该函数永远不是有效constexpr函数。

于 2012-02-05T20:32:33.427 回答
2

你应该看看Boost.Detail.Endian

它是几个架构到它们的字节序的映射(通过宏 BOOST_BIG_ENDIAN、BOOST_LITTLE_ENDIAN 和 BOOST_PDP_ENDIAN)。据我所知,除了这样的列表之外,没有实际的方法可以在编译时确定字节顺序。

对于使用 Boost.Detail.Endian 的示例实现,您可以查看我希望通过审核以提交给 Boost 的库:httpsbyte_order.hpp : //bitbucket.org/davidstone/endian/ (相关文件unsigned.hpp为以及如果您只想使用我的实现)。

于 2012-04-03T04:10:03.130 回答
0

如果实现了 N3620 - 网络字节顺序转换,您将能够使用 constexprntoh来检查字节序,但请记住,像中间字节序这样的罕见架构,您将永远无法支持所有它们。

于 2013-11-01T22:20:50.970 回答