Visual Studio stdint. 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;
但是,大小调整的整数类型使用__intN
语法,如下所述:https://learn.microsoft.com/en-us/cpp/cpp/int8-int16-int32-int64?view=msvc-170
例如,使用int32_t
与使用__int32
之间有什么区别吗?
我想我有点困惑,如果int32_t
typedef的目的是作为ANSI C99标准来抽象特定的编译器语法(例如,这样你就可以在Visual Studio和gcc C代码中使用int32_t
),那么我不知道为什么Visual Studio中的typedef不是:typedef __int32 int32_t;
假设代码库具有以下内容:
#ifdef _MSC_VER
typedef __int64 PROD_INT64;
#else
typedef int64_t PROD_INT64;
#endif
它在任何地方都使用PROD_INT64
来表示64位有符号整数,并且它是在Visual Studio和gcc中编译的。
它可以简单地在Visual Studio和gcc中使用int64_t
吗?这似乎是在Visual Studio中将__int64
改为long long
。
3条答案
按热度按时间mbjcgjjk1#
问:使用int32_t和使用__int32之间有什么区别吗?
答:是的。
https://stackoverflow.com/a/25090719/421195
C标准规定(第7.1.3节):
以下划线和大写字母或另一个下划线开始的所有标识符始终保留以供任何使用。
所有以下划线开始的标识符始终保留用作普通和标记名称空间中文件范围的标识符。
这意味着,例如,实现(编译器或标准头文件)可以使用名称__FOO来表示任何它喜欢的东西。如果你在自己的代码中定义了这个标识符,你的程序的行为是未定义的。如果你“幸运”,你将使用一个碰巧没有定义它的实现,你的程序将按预期工作。
换句话说,对于任何 NEW 代码,都应该使用“int32_t”。
zu0ti5jz2#
大小的整数类型使用
__intN
语法,如下所述:https://learn.microsoft.com/en-us/cpp/cpp/int8-int16-int32-int64?view=msvc-170你的措辞表明,你认为
__intN
语法比其他所有替代语法都更正确或更基本。你链接的文档并不是这么说的。它只是定义了那些特定形式的含义。在Microsoft C中,这些形式比Microsoft的旧单下划线形式更受欢迎(_intN
),但是没有特别的理由认为它们比其它替代物更优选,例如包含stdint.h
时可用的intN_t
表单。__intN
类型的关键区别特征是它们是内置的,* 不 * 包含任何特定的头部。例如,使用
int32_t
与使用__int32
之间有什么区别吗?int32_t
与__int32
是相同的类型,但前者是标准C,而后者不是。int32_t
,您需要包含stdint.h
,而__int32
是内置在MSVC中的。我不知道为什么Visual Studio中的typedef不是:
typedef __int32 int32_t
;这是一个实现决策,可能有也可能没有经过深思熟虑的原因,只要实现提供了正确的定义--没有理由认为MSVC做了其他的事情--您就不应该关心细节。
假设代码库具有以下内容:
它在任何地方都使用
PROD_INT64
来表示64位有符号整数,并且它是在Visual Studio和gcc中编译的。它可以简单地在Visual Studio和gcc中使用
int64_t
吗?是的,我当然会这么做。
这似乎是在Visual Studio中将
__int64
更改为long long
。这是一个没有区别的区别。这两个拼写在msvc中给你相同的类型。
4nkexdtk3#
从我的顶部评论...
stdint.h
由编译器提供,而不是libc或操作系统。它提供了可移植性保证(例如int32_t
将是32位)。编译器设计人员可以:或者,他们可以:
后者是大多数
stdint.h
文件所做的(因为它们没有__int*
类型)。VS编译器的设计者可能只是抓取了标准stdint. h的一个副本,而没有费心去修改它。
你的观点是正确的,这只是编译器作者的一个设计选择(或者说没有),只要使用标准的/可移植的
int32_t
就可以了,不用担心;-)历史注解:
stdint.h
是相对较新的。在20世纪80年代,MS有[16位] MS/DOS。当时许多基于mc68000的微处理器将int
定义为32位。但是,在MS C编译器上,int
是16位,因为这最适合8086架构。stdint.h
在当时并不存在。但是,如果它存在,它将需要:因为
long
是为MS8086编译器定义32位整数的唯一方法。当64位计算机出现时,POSIX兼容的计算机允许
long
以arch/模式"浮动"。在32位archs上是32位,在64位archs上是64位。这就是LP64
内存模型。最初的理由如下:https://unix.org/version2/whatsnew/lp64_wp.htm
但是,由于微软长期以来使用
long
作为32位整数,它无法做到这一点。太多在8086天内编写的程序如果重新编译就会崩溃。IIRC [我可能是错的]:
1.微软提出了
__int64
和LONGLONG
作为类型。1.他们必须为指针定义[另一个]抽象类型[记住
near
和far
指针,任何人;-)?]所以,IMO,这在一定程度上是因为所有的MS疯狂,促使创建
stdint.h
摆在首位。