【问题标题】:How to check if fixed width integers are defined如何检查是否定义了固定宽度的整数
【发布时间】:2020-01-01 12:36:41
【问题描述】:

在 C++ 中,固定宽度整数定义为 optional,但我似乎找不到推荐的方法来检查它们是否实际定义。

检查固定宽度整数是否可用的便携方法是什么?

【问题讨论】:

  • 好像没有feature test macro,不过我想你可以做#if defined(INT8_MIN)
  • 如果 std 库没有为此提供功能测试宏,那么您可以检查您使用的工具链是否为它提供了一个或允许您定义自己的测试。例如,CMake 允许您通过编译定义的 cpp 文件并根据编译是否失败或未设置您可以定义的宏来测试某些语言功能。
  • 如果您更喜欢 autoconf 而不是 cmake,它会为它们预定义测试。 AC_TYPE_INT8_T
  • 如果有人在stdint 中有任何标签分数,则应将IMO cstdint 指定为同义词(stackoverflow.com/tags/stdint/synonyms)。我认为我们不需要单独的 C 和 C++ 标记来处理这个晦涩难懂的东西。题主标签就够了。
  • @PeterCordes 这次成功了:stackoverflow.com/tags/stdint/synonyms

标签: c++ c++11 types stdint cstdint


【解决方案1】:

一般来说……你不知道。

如果您需要使用固定大小的整数类型,那么这意味着您明确需要这些类型具有特定的大小。也就是说,如果您无法获得这些大小的整数,您的代码将无法正常工作。所以你应该只使用它们;如果有人在缺少上述类型的编译器上使用您的代码,那么您的代码将无法编译。这很好,因为如果你的代码编译了,它就不会工作。

如果您实际上并不需要 固定大小的整数,而只是出于其他原因想要它们,那么请使用int_least_* 类型。如果实现可以准确地为您提供该大小,那么 least_* 类型将具有该大小。

【讨论】:

  • 这不是真的。我已经为以前不支持 uint8_t 的平台编写了实现 operator= / etc 的存根直通。但出于效率和调试目的,除非确实有必要,否则您不想使用直通。
  • @TLW:“我已经为以前不支持 uint8_t 的平台编写了实现 operator= / 等的存根直通。”好的,但是......为什么?您正在编写什么代码,需要确定一个字节是 8 位(这可能是您使用 uint8_t 的原因),但是这段代码需要在一个字节不是 8 位的平台上运行(其中,除了使用旧的 C++ 实现之外,这将是 uint8_t 不可用的唯一原因)?也就是说,除了向后兼容性之外,您为什么需要这样做?
  • 专有所以不能说太多。共享代码库需要支持,除其他外,相当古怪的硬件堆栈。 uint8_t 比以前的 ad-hoc(并且经常被破坏)方法更加清晰
  • 如果你有一个算法用例如8 位字节,直通是您可以编写一次并且易于测试的东西。而修复每个地方都是临时的,而且很容易出现微妙的错误。 O(1)O(n) 的努力。人们使用例如相同的原因uint16_t。您在问“为什么不使用 uint32_t 并自己进行转换?”,答案应该很明显。
  • @TLW: "人们使用例如 uint16_t 的原因相同。" 这不是 我的 使用 uint16_t 的原因。我的原因是我正在与一个设备/格式/等进行通信,该设备/格式/等期望使用我的机器的字节序将精确的 16 位数据格式化为二进制无符号整数,如果我无法获得一个类型准确地说,与它进行有效沟通要困难得多。我的程序(以及我与之一起使用的 API)基本上无法在不提供该功能的机器上运行
【解决方案2】:

要确定是否提供了固定宽度的整数类型,您可以检查是否定义了相应的 [U]INT*_MAX[U]INT*_MIN 宏。

// may be necessary for your C++ implementation
#define __STDC_LIMIT_MACROS 
#include <cstdint>

#ifdef INT32_MAX
// int32_t must be available to get here
int32_t some32bitIntVariable;
#endif

根据7.20 Integer types &lt;stdint.h&gt;, paragraph 4 of the C11 standard(注意加粗部分):

对于此处描述的实现提供的每种类型,&lt;stdint.h&gt; 应声明 typedef 名称并定义关联的宏。相反,对于此处描述的每种实现方式未提供的类型,&lt;stdint.h&gt; 不应声明 typedef 名称也不应定义关联的宏

C++ 通过&lt;cstdint&gt; 继承C 实现。有关详细信息,请参阅&lt;cstdint&gt; vs &lt;stdint.h&gt;。有关__STDC_LIMIT_MACROS 的详细信息,另请参阅What do __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS mean?

因此,如果int32_t 可用,则INT32_MAXINT32_MIN 必须是#define'd。相反,如果int32_t 不可用,则INT32_MAXINT32_MIN 都不允许成为#define'd。

请注意,as @NicolBolas stated in another answer,可能没有必要实际检查。

【讨论】:

  • 检查[U]INT*_C而不是最小和最大宏会更短
  • @phuclv 除了那不是一回事。例如INT64_C 是在 int64_least_t 可用时定义的,而不是在 int64_t 可用时定义的。参考documentation
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
相关资源
最近更新 更多