【问题标题】:Is it possible to use std::endian if it is available, otherwise do something else?如果 std::endian 可用,是否可以使用它,否则做其他事情?
【发布时间】:2020-07-21 16:55:46
【问题描述】:

从 C++20 开始,我们可以:

constexpr bool is_little_endian = std::endian::native == std::endian::little;

如果可用,我希望有执行此操作的代码,否则执行运行时检测。这可能吗?

也许代码看起来像:

template<bool b = std_endian_exists_v> constexpr bool is_little_endian;
template<> constexpr bool is_little_endian<true> = std::endian::native == std::endian::little;
template<> constexpr bool is_little_endian<false> = runtime_detection();

我知道通过预处理器测试__cplusplus 是可能的,但是编译器在各个阶段支持C++20,因此这不是一个可靠的指标。

【问题讨论】:

  • "当前版本的godbolt gcc 9.3 -std=c++2a没有std::endian" godbolt.org/z/aRFCps
  • 你可以让你的构建系统通过尝试编译一个使用std::endian的测试程序来检测它,然后有条件地定义一个预处理器符号,但我觉得这不是你正在寻找的答案.
  • @cpplearner 嗯很奇怪,我做了几乎完全相同的事情,但失败了,哦,好吧
  • 我正要提出一个 cough 预处理器解决方案来检查 VC++ 与 g++ 的定义。但我怀疑你想要一个通用的解决方案。具有讽刺意味的是,这就是 reference page 提出的实现方式。
  • 我认为constexprruntime_detection() 不能在同一行 ;-)

标签: c++ endianness constexpr c++20


【解决方案1】:

我知道通过预处理器测试__cplusplus 是可能的,但是C++20 中的编译器阶段在各个阶段都支持,所以这在任何一个方向上都不是一个可靠的指标。

确实!事实上,这就是为什么我们现在有了一种全新的方法来检测对处于不同发布阶段的编译器的功能支持:功能测试宏!如果你看SD-FeatureTest,标准中采用的每种语言和库特性对应的宏都有大表,一旦采用一个特性,每个宏都会用指定的值定义。

在您的具体情况下,您需要__cpp_lib_endian

现在库宏的问题是我们开始添加它们之前我们添加了一个放置它们的位置 - 这将是&lt;version&gt;。如果您使用的是具有&lt;version&gt; 的编译器(这将是 gcc 9+,带有 libc++ 的 clang 7+,并且我不了解 MSVC),您可以将其包含在内。但它可能不会,因此您可能还必须尝试包含正确的标头(在本例中为 &lt;bit&gt;)。

#if __has_include(<bit>)
#  include <bit>
#  ifdef __cpp_lib_endian
#    define HAS_ENDIAN 1
#  endif
#endif

#ifdef HAS_ENDIAN
constexpr bool is_little_endian = std::endian::native == std::endian::little;
#else
constexpr bool is_little_endian = /* ... figure it out ... */;
#endif

虽然这样做可能更好:

#ifdef HAS_ENDIAN
using my_endian = std::endian;
#else
enum class my_endian {
   // copy some existing implementation
};
#endif

constexpr bool is_little_endian = my_endian::native == my_endian::little;

【讨论】:

  • 也许这需要调整一下,runtime_detection() 不应分配给 constexpr 变量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
相关资源
最近更新 更多