在编译时测试endianess:这个constexpr函数是否符合标准?

时间:2012-02-05 20:10:55

标签: c++ c++11 constexpr

在编译时搜索了一种检查endianess的方法后,我提出了以下解决方案:

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

对于第二个案例,海湾合作委员会说error: accessing value of ‘a’ through a ‘char’ glvalue in a constant expression。我无法在禁止此类事件的标准中找到任何内容。也许有人可以澄清GCC在哪种情况下是正确的?

3 个答案:

答案 0 :(得分:10)

这是我从Clang 3.1 ToT得到的:

  

错误:constexpr函数永远不会产生常量表达式

§5.19 [expr.const]

  

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

     

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

     
      
  • [...]
  •   
  • a reinterpret_cast(5.2.10);
  •   

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

答案 1 :(得分:2)

您应该查看Boost.Detail.Endian

它是几种体系结构到其字节序的映射(通过宏BOOST_BIG_ENDIAN,BOOST_LITTLE_ENDIAN和BOOST_PDP_ENDIAN)。据我所知,除了像这样的列表之外,没有实际的方法来确定编译时的字节序。

对于使用Boost.Detail.Endian的示例实现,您可以看到我希望获得审核以提交Boost的库:https://bitbucket.org/davidstone/endian/(相关文件为byte_order.hpp,但{如果你想只使用我的实现,{1}}也是必要的。

答案 2 :(得分:0)

如果实施N3620 - 网络字节顺序转换,您将能够使用constexpr ntoh来检查字节顺序,但请记住,有一些罕见的体系结构,如中端,您永远无法支持所有这些。