C语言 定大小的整数类型可以和typedef互换使用吗?

yqyhoc1h  于 2023-01-12  发布在  其他
关注(0)|答案(3)|浏览(111)

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

mbjcgjjk

mbjcgjjk1#

问:使用int32_t和使用__int32之间有什么区别吗?
答:是的。

https://stackoverflow.com/a/25090719/421195
C标准规定(第7.1.3节):
以下划线和大写字母或另一个下划线开始的所有标识符始终保留以供任何使用。
所有以下划线开始的标识符始终保留用作普通和标记名称空间中文件范围的标识符。
这意味着,例如,实现(编译器或标准头文件)可以使用名称__FOO来表示任何它喜欢的东西。如果你在自己的代码中定义了这个标识符,你的程序的行为是未定义的。如果你“幸运”,你将使用一个碰巧没有定义它的实现,你的程序将按预期工作。
换句话说,对于任何 NEW 代码,都应该使用“int32_t”。

zu0ti5jz

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之间有什么区别吗?

  • 在Windows上,int32_t__int32是相同的类型,但前者是标准C,而后者不是。
  • 要使用int32_t,您需要包含stdint.h,而__int32是内置在MSVC中的。

我不知道为什么Visual Studio中的typedef不是:typedef __int32 int32_t;
这是一个实现决策,可能有也可能没有经过深思熟虑的原因,只要实现提供了正确的定义--没有理由认为MSVC做了其他的事情--您就不应该关心细节。
假设代码库具有以下内容:

#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
这是一个没有区别的区别。这两个拼写在msvc中给你相同的类型。

4nkexdtk

4nkexdtk3#

从我的顶部评论...
stdint.h由编译器提供,而不是libc或操作系统。它提供了可移植性保证(例如int32_t将是32位)。编译器设计人员可以:

typedef __int32 int32_t;

或者,他们可以:

typedef int int32_t;

后者是大多数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在当时并不存在。但是,如果它存在,它将需要:

typedef long int32_t;

因为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.微软提出了__int64LONGLONG作为类型。
1.他们必须为指针定义[另一个]抽象类型[记住nearfar指针,任何人;-)?]
所以,IMO,这在一定程度上是因为所有的MS疯狂,促使创建stdint.h摆在首位。

相关问题