在编译时测试endianes:根据标准,这个constexpr函数是否正确
Testing endianess at compile-time: is this constexpr function correct according to the standard?
经过一番搜索,我找到了以下解决方案:
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在哪种情况下是正确的?
这是我从Clang 3.1 ToT:中得到的
错误:constexpr函数从不生成常量表达式
§5.19 [expr.const]
p1某些上下文要求表达满足本款详细规定的附加要求;根据表达式是否满足这些要求,其他上下文具有不同的语义满足这些要求的表达式称为常量表达式
p2条件表达式是核心常量表达式
- […]
reinterpret_cast
(5.2.10)
因此,(char*)&(a)
计算为reinterpret_cast
,因此该函数永远不是有效的constexpr
函数。
您应该查看Boost.Detail.Endian
它是几个体系结构到其端序的映射(通过宏BOOST_BIG_ENDAN、BOOST_TTLE_ENDIAN和BOOST_PDP_ENDAN)。据我所知,除了这样的列表之外,在编译时没有实际的方法来确定endianness。
对于使用Boost.Detail.Endian的示例实现,您可以看到我希望在提交给Boost时得到审查的库:https://bitbucket.org/davidstone/endian/(相关文件是byte_order.hpp
,但如果您只想使用我的实现,unsigned.hpp
也是必要的)。
如果实现了N3620-网络字节顺序转换,您将能够使用constexpr ntoh
来检查endianness,但请记住,有一些罕见的架构,如middle endian,您永远无法支持所有这些架构。
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 有人能分解一下这个c++模板的语法吗
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 多成员Constexpr结构初始化
- 条件constexpr函数
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 如何让编译器忽略这个计算结果为 false 的 if-constexpr?
- 为什么这个嵌套的 lambda 不被认为是 constexpr?
- 如何理解这个例子中的constexpr
- 为什么可变参数函数模板中的这个 constexpr 不是常数?
- 如何在 C++11 中编写这个 C++17 静态 constexpr 方法
- 为什么 if constexpr 不会使这个核心常量表达式错误消失?
- 这个constexpr整数不是空指针常量吗
- 如何使这个"template / constexpr"构造更优雅/不那么冗长?
- C++:为什么这个 constexpr 不是编译时常数
- 如何将这个运行时高效的函数转换为constexpr
- 为什么这个模板 constexpr 函数不能在 gcc 上编译,但在 clang 上效果很好?
- 在编译时测试endianes:根据标准,这个constexpr函数是否正确
- 这个代码怎么可能是constexpr?(std::chrono)
- 为什么我不能在函数中使用constexpr值,但我可以在这个值的作用域内做同样的事情