这是一个可能无聊的问题,我应该知道它的答案.
十五年前左右,我所看到的很多C代码在平台特定的#ifdef
s 中有大量的整数typedef .似乎我看过的每个程序或库都有自己的,互不兼容的typedef汤.我当时并不知道很多关于编程的内容,只是为了告诉编译器你想要使用什么类型的整数,它似乎是一个奇怪的箍.
我已经在脑海中编写了一个故事来解释那些typedef是关于什么的,但我实际上并不知道它是否属实.我的猜测基本上是当C首次开发和标准化时,没有意识到能够平台独立地获得特定大小的整数类型是多么重要,因此所有原始C整数类型可能是不同的不同平台上的尺寸.因此,每个尝试编写可移植C代码的人都必须自己编写代码.
它是否正确?如果是这样,如何被程序员预计将使用C整数类型?我的意思是,在一个低级别的语言中,有很多有点麻烦,能说"这是一个32位整数"并不重要吗?自从该语言在1989年被标准化以来,肯定有人认为人们会尝试编写可移植代码吗?
Joh*_*all 66
当C开始时,计算机的同质性较低,而且与现在的连接相比要少得多.对于可移植性来说,更重要的是int类型是计算机的自然大小.在36位系统上要求精确的32位整数类型可能会导致代码效率低下.
然后是普适的网络,您正在使用特定的线上大小字段.现在,互操作性看起来有很大不同.而'八位字节'成为事实上的数据类型量子.
现在你需要8位精确倍数的整数,所以现在你得到了typedef汤,然后最终标准赶上了,我们有标准的名字,并且汤不是必需的.
chu*_*ica 18
C的早期成功是由于它能够灵活地适应几乎所有现有的变体架构@John Hascall:
1)原生整数大小为8,16,18,24,32,36等位,
2)变量有符号整数模型: 2的补码,1的补码,有符号整数和
3)各种端序,大,小和其他.
随着编码的发展,数据的算法和交换推动了更大的一致性,因此需要跨平台满足1和2的类型.编码器就像typedef int int32
在里面一样#if ...
.如OP所述,其中的许多变化产生了汤.
C99引入(u)int_leastN_t, (u)int_fastN_t, (u)intmax_t
了便携式但有些最小位宽度类型.N = 8,16,32,64需要这些类型.
还介绍了半可选类型(见下面的**)(u)intN_t
,它们具有附加属性,它们必须是2的补码且没有填充.正是这些流行的类型被广泛需要并用于稀释整数汤.
程序员如何期望使用C整数类型?
通过编写不强烈依赖于位宽的灵活代码.strtol()
仅使用LONG_MIN, LONG_MAX
不考虑位宽/字节/整数编码的代码是相当容易的.
然而,许多编码任务需要精确的宽度类型和2的补码,以便于高性能编码.在这种情况下,最好放弃36位机器的便携性和32位符号幅度的机器,并坚持2 N宽(带符号2的补码)整数.我想到了各种CRC和加密算法和文件格式.因此需要固定宽度类型和指定(C99)方式来做到这一点.
今天仍然存在仍需要管理的陷阱.示例:通常的促销int/unsigned
会失去一些控制权,因为这些类型可能是16,32或64.
**
这些类型是可选的.但是,如果实现提供宽度为8,16,32或64位的整数类型,没有填充位,并且(对于带有二进制补码表示的有符号类型),它应定义相应的typedef名称.C11 7.20.1.1确切宽度整数类型3
Yim*_*ong 11
我记得那个时期,我也犯了同样的罪行!
一个问题是它的大小int
,它可以是相同的short
,long
或者在它们之间.例如,如果您使用的是二进制文件格式,则必须保持一致.字节也可以订购复杂的东西.许多开发人员都采用了懒惰的方式而只是做fwrite
了什么,而不是逐字节地选择数字.当机器升级到更长的字长时,一切都崩溃了.所以typedef
很容易解决这个问题.
如果性能是一个问题,因为它通常是当时的,int
保证是机器最快的自然尺寸,但如果你需要32位,并且int
比这短,你就有翻车的危险.
在C语言中,sizeof()
不应该在预处理器阶段解决,这使事情变得复杂,因为你无法做到这一点#if sizeof(int) == 4
.
就个人而言,一些基本原理也只是从汇编语言的心态工作,不是不愿意抽象出什么样的概念short
,int
并且long
是.那时候,汇编程序经常在C中使用.
如今,有很多非二进制文件格式,JSON,XML等,二进制表示是什么并不重要.同样,许多流行的平台已经确定了32位int
或更长时间,这通常足以满足大多数用途,因此翻转的问题较少.
C是20世纪70年代早期的产品,当时计算生态系统非常不同.而不是数百万台计算机都通过扩展网络相互通信,全世界可能有十万个系统,每个系统运行一些单片应用程序,系统之间几乎没有通信.您不能假设任何两个体系结构具有相同的字大小,或以相同的方式表示有符号整数.市场仍然很小,以至于没有任何需要标准化,计算机之间没有相互交谈(很多),也没有人谈论可移植性.
如果是这样,程序员如何期望使用C整数类型?
如果您想编写最大可移植代码,那么您不会假设超出标准保证的任何内容.在这种情况下int
,这意味着你没有假设它可以表示范围之外的任何东西[-32767,32767]
,你也没有假设它将以2的补码表示,你也没有假设它是一个特定的宽度(它可能更宽)超过16位,但如果它包含任何填充位,则仍然只表示16位范围).
如果您不关心可移植性,或者您正在做一些本质上不可移植的东西(通常情况下有点麻烦),那么您使用的任何类型都符合您的要求.
我做的主要是高级应用程序编程,所以我不太担心表示而不是关于范围.即便如此,我偶尔也需要深入研究二进制表示,它总是让我陷入困境.我记得在90年代早期编写了一些必须在经典MacOS,Windows 3.1和Solaris上运行的代码.我为32位掩码创建了一堆枚举常量,它在Mac和Unix机器上运行良好,但无法在Windows机器上编译,因为在Windows int
上只有16位宽.