0

Visual Studio 14stdint.h头中有固定宽度整数类型的定义,但如果您真正查看那里的定义,它们只是委托回原语。定义如下:

typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef long long          int64_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;

stdint.h那么,如果它所做的只是回退到原语,是否有任何理由使用它?我也知道 Visual Studio 不只是在编译时替换这些定义,因为如果您尝试将 an 打印int8_t到控制台,您将得到一个 Unicode 字符而不是数字,因为它实际上只是一个signed char.

编辑

因为人们指出,他们在逻辑上没有其他东西可以定义,我认为我的问题需要重述。

为什么在 C++ 规范中声明它将具有 8、16、32 和 64 位固定长度的整数的标头将这些整数定义为根据定义可以是编译器想要的任何大小的类型(放入其他人在另一个问题中所说的方式The compiler can decide that an int will a 71 bit number stored in a 128 bit memory space where the additional 57 bits are used to store the programmers girlfriends birthday.)?

4

4 回答 4

4

不同的平台对原语的定义不同。在一个平台上int可能是 16 位,而在另一个平台上是 32 位。如果您严格依赖具有一定宽度的变量,则应使用 中的类型stdint.h,这些类型将始终typedef正确地对应于当前平台上它们各自的原语。

于 2017-02-05T21:55:11.920 回答
3

那么,如果 stdint.h 所做的只是回退到原语,那么有什么理由使用它?

它还能做什么?

头文件中定义的所有类型都可以追溯到内置类型。

此标头只是为您提供方便的、标准定义的、保证一致的别名。

于 2017-02-05T22:02:59.020 回答
1

我从原始问题和重述问题中了解到,对保证宽度整数(我说保证是因为并非所有类型stdint.h都具有固定宽度)以及它们解决的实际问题存在误解。

C/C++ 定义了诸如 , 等原语intlong intlong long int简单起见,让我们关注最常见的,即int. C 标准定义的是,它int至少应该是 16 位宽。虽然,所有广泛使用的 x86 平台上的编译器实际上会在您定义一个 32 位宽的整数时为您提供int. 发生这种情况是因为 x86 处理器可以直接从内存中获取 32 位宽的字段(32 位 x86 CPU 的字长),按原样提供给 ALU 以进行 32 位运算并将其存储回内存,而无需执行任何操作班次,填充等,这非常快。但并非每个编译器/架构组合都是如此。如果你在一个嵌入式设备上工作,例如一个非常小的 MIPS 处理器,当你定义一个int. 因此,原语的宽度由编译器指定,仅取决于目标平台的硬件功能,相对于标准定义的最小宽度。是的,在具有例如 25 位 ALU 的奇怪架构上,您可能会得到一个 25 位的int.

为了让一段 C/C++ 代码在许多不同的编译器/硬件组合之间可移植,stdint.h提供了保证一定宽度(或最小宽度)的 typedef。因此,例如,当您想使用 16 位有符号整数(例如,用于节省内存或 mod 计数器)时,您不必担心是否应该使用intor short,只需使用int16_t. 编译器的开发人员将为您提供一个正确构造的方法stdint.h,它将请求的固定大小整数类型定义为实现它的实际原语。这意味着,在 x86 上,anint16_t可能会被定义为short,而在小型嵌入式设备上,您可能会得到int, 所有这些映射都由编译器的开发人员维护。

于 2018-09-03T15:33:06.013 回答
0

在回答重述的问题时,不是编译器选择将生日存储在高 57 位中。这是一个开发商。编译器不能对整数类型使用它想要的任何位深度。它将使用编译器的开发人员告诉它使用的任何位深度,并且开发人员将根据C++ 标准的要求选择这些位深度。一旦编译器被配置和编译,位深度将不会改变1。在您更改编译器或编译器版本之前,将保证 71 位。

编写好的代码已经够难了,编译器不会向你抛出变量。考虑可变位深度会发生什么。一个在周二的构建中很好的输入溢出并导致一架喷气式飞机坠毁,因为周三编译器执行了一些计算并决定它永远不会看到超过 17 位的任何内容。

1我想您可以构建一个编译器,在运行时从配置文件中加载各种整数大小,但我怀疑这会使编写优化器变得异常复杂。

于 2017-02-05T23:52:55.010 回答