你如何确定你的机器是否支持 C 中的标准整数数据类型?
How do you determine if your machine supports a standard integer datatype in C?
我有点熟悉 C 中 stdint.h 的概念。通过显式声明整数的大小,头文件将用该机器上的适当整数替换#define 整数。例如,如果我的机器有 16 位无符号整数,uint32_t
将替换为 long unsigned int
。
但是,假设您的机器最多只支持 32 位整数。如果你使用 int64_t
会发生什么?如果本机不支持此整数大小,那么如何解决这个问题,因为没有可以修复它的替代方法?
编译器会抛出错误提示无法解析吗?或者它会尝试使用两个 32 位分配来保存 64 位数据类型吗?
计算机(处理器)不限制整数类型的高位宽。编译器施加限制。硬件确实会影响处理大整数类型的复杂性和效率。如果有足够的时间和内存,即使 1-bit platform 也可以进行 64 位数学运算。
兼容的 C 编译器,C99 及更高版本,支持至少高达 64 位的整数宽度。
是的,32 位机器通常使用一对 32 位内部对象处理 64 位操作。
说清楚。 C99 编译器需要处理 至少 64 位的一些整数类型以实现所需的 long long
。平台可能或可能实现 uint64_t
,64 位宽度,无填充,2 的补码整数类型。它的实施非常普遍。
unsigned long long ull; // must exist
#include <stdint.h>
uint_least64_t uleast64; // must exist
uint64_t u64; // may exist
如果不支持某种 stdint 类型,代码将无法编译。您可以像这样检查它们是否受支持:
#include <stdint.h>
#ifndef UINT64_MAX
#error uint64_t not supported
#endif
如果您的编译器支持某种类型但您的 CPU 不支持,这意味着一些编译器库代码将被静默调用以模拟更大的类型。
例如,如果您在 8 位微控制器上使用 uint32_t
,编译器往往会支持它,但由于该类型仅通过软件模拟,因此生成的机器代码会变得又大又慢。
在特定 C 实现的 stdint.h
(作为 typedef
而非宏)中声明的 exact-width 类型都是可选的。仅当它们实际上提供具有所需特征的数据类型时,才需要实现声明它们。
在您的特定示例中,如果所讨论的 C 实现不提供无填充位的 64 位二进制补码整数类型,则其 stdint.h
将不会声明类型 int64_t
。如果您随后使用该类型而不自己声明它,编译器将拒绝您的代码。
需要stdint.h
提供的其他一些类型;一致的实现肯定会提供它们。对于可选的,您可以通过测试是否为它们的限制定义了相应的宏来测试编译器是否提供它们(例如 INT64_MAX
)。
我有点熟悉 C 中 stdint.h 的概念。通过显式声明整数的大小,头文件将用该机器上的适当整数替换#define 整数。例如,如果我的机器有 16 位无符号整数,uint32_t
将替换为 long unsigned int
。
但是,假设您的机器最多只支持 32 位整数。如果你使用 int64_t
会发生什么?如果本机不支持此整数大小,那么如何解决这个问题,因为没有可以修复它的替代方法?
编译器会抛出错误提示无法解析吗?或者它会尝试使用两个 32 位分配来保存 64 位数据类型吗?
计算机(处理器)不限制整数类型的高位宽。编译器施加限制。硬件确实会影响处理大整数类型的复杂性和效率。如果有足够的时间和内存,即使 1-bit platform 也可以进行 64 位数学运算。
兼容的 C 编译器,C99 及更高版本,支持至少高达 64 位的整数宽度。
是的,32 位机器通常使用一对 32 位内部对象处理 64 位操作。
说清楚。 C99 编译器需要处理 至少 64 位的一些整数类型以实现所需的 long long
。平台可能或可能实现 uint64_t
,64 位宽度,无填充,2 的补码整数类型。它的实施非常普遍。
unsigned long long ull; // must exist
#include <stdint.h>
uint_least64_t uleast64; // must exist
uint64_t u64; // may exist
如果不支持某种 stdint 类型,代码将无法编译。您可以像这样检查它们是否受支持:
#include <stdint.h>
#ifndef UINT64_MAX
#error uint64_t not supported
#endif
如果您的编译器支持某种类型但您的 CPU 不支持,这意味着一些编译器库代码将被静默调用以模拟更大的类型。
例如,如果您在 8 位微控制器上使用 uint32_t
,编译器往往会支持它,但由于该类型仅通过软件模拟,因此生成的机器代码会变得又大又慢。
在特定 C 实现的 stdint.h
(作为 typedef
而非宏)中声明的 exact-width 类型都是可选的。仅当它们实际上提供具有所需特征的数据类型时,才需要实现声明它们。
在您的特定示例中,如果所讨论的 C 实现不提供无填充位的 64 位二进制补码整数类型,则其 stdint.h
将不会声明类型 int64_t
。如果您随后使用该类型而不自己声明它,编译器将拒绝您的代码。
需要stdint.h
提供的其他一些类型;一致的实现肯定会提供它们。对于可选的,您可以通过测试是否为它们的限制定义了相应的宏来测试编译器是否提供它们(例如 INT64_MAX
)。