简体   繁体   English

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

[英]Testing endianess at compile-time: is this constexpr function correct according to the standard?

After some search for a way to check endianess at compile-time I've come up with the following solution: 在编译时搜索了一种检查endianess的方法后,我提出了以下解决方案:

static const int a{1};

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

GCC accepts this code only in some contexts where constexpr is required: GCC仅在需要constexpr的某些上下文中接受此代码:

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

For the second case, GCC says error: accessing value of 'a' through a 'char' glvalue in a constant expression . 对于第二种情况,GCC说error: accessing value of 'a' through a 'char' glvalue in a constant expression I couldn't find anything in the standard that forbids such thing. 我无法在禁止此类事件的标准中找到任何内容。 Maybe someone could clarify in which case GCC is correct? 也许有人可以澄清GCC在哪种情况下是正确的?

This is what I get from Clang 3.1 ToT: 这是我从Clang 3.1 ToT得到的:

error: constexpr function never produces a constant expression 错误:constexpr函数永远不会产生常量表达式

§5.19 [expr.const]

p1 Certain contexts require expressions that satisfy additional requirements as detailed in this sub-clause; p1某些上下文要求表达式满足本子条款中详述的其他要求; other contexts have different semantics depending on whether or not an expression satisfies these requirements. 其他上下文具有不同的语义,具体取决于表达式是否满足这些要求。 Expressions that satisfy these requirements are called constant expressions . 满足这些要求的表达式称为常量表达式

p2 A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression: p2 条件表达式核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式:

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

So, (char*)&(a) evaluates to a reinterpret_cast , as such the function is never a valid constexpr function. 因此, (char*)&(a)求值为reinterpret_cast ,因此该函数永远不是有效的constexpr函数。

You should look into Boost.Detail.Endian 你应该看看Boost.Detail.Endian

It is a mapping of several architectures to their endianness (through the macros BOOST_BIG_ENDIAN, BOOST_LITTLE_ENDIAN, and BOOST_PDP_ENDIAN). 它是几种体系结构到其字节序的映射(通过宏BOOST_BIG_ENDIAN,BOOST_LITTLE_ENDIAN和BOOST_PDP_ENDIAN)。 As far as I know, there is no actual way to determine the endianness at compile time, other than a list like this. 据我所知,除了像这样的列表之外,没有实际的方法来确定编译时的字节序。

For an example implementation that uses Boost.Detail.Endian, you can see the library I'm hoping to get reviewed for submission to Boost: https://bitbucket.org/davidstone/endian/ (the relevant file is byte_order.hpp , but unsigned.hpp is necessary as well if you want to just use my implementation). 对于使用Boost.Detail.Endian的示例实现,您可以看到我希望获得提交给Boost的库: httpsbyte_order.hpp (相关文件是byte_order.hpp ,但是如果你想使用我的实现, unsigned.hpp也是必要的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM