目录
int类型长度由什么决定的?
可能在很多书籍上会看到,C/C++的int类型长度随系统而定。这里的系统,并不是操作系统,也不是硬件平台,而是编译器。编译器是直接阅读源代码并决定int长度的,只是大家为了简化,常说是随系统而定。一些编译器是和系统位数统一,造成了假象,32位的硬件,32位的操作系统,编译器同样把int当成32位,以为int长度和硬件/OS真有关系。
64位编译器int类型依然是32位?
- 32位编译器,int和long一般都设置为4字节。
例如i686-w64-mingw32-gcc.exe. - 64位编译器,Linux平台long一般提升到8字节,int一般保持为4字节;Windows平台long和int保持为4字节,用long long表示8字节。这是由于Win64使用LLP64模型,Linux 64位使用LP64.
- 关于Windows 64位LLP64模型,可参考: Why did the Win64 team choose the LLP64 model?
Ubuntu 22.04 64位系统默认gcc是64位,可执行文件在/usr/bin/x86_64-linux-gnu-gcc,Windows 10 64位Cygwin gcc.exe同样也是64位,编译代码printf("%d %d\n", sizeof(int), sizeof(long))会得到"4 8". 如果换成上面提到的i686-w64-mingw32-gcc.exe编译,得到"4 4".
32位和64位
特别提到它们,因为它们曾经让无数程序员在痛苦的4字节和8字节周旋,痛苦的根源在于语言标准没有强制规定int和long究竟占几个字节。Java和C#作为中间件编程语言,一统类型大小,之后再无痛苦。
- Linux kernel driver接口提供的int类型参数造成用户空间和内核空间不匹配。
- 32位系统到64位系统迁移,用32位还是64位编译器,int的大小截然不同。
究竟什么是32位什么是64位系统?
一般而言,CPU位数是指CPU最轻松操作的寄存器大小。
int和long的区别
作为基本类型,一般而言,编译器对于int和long的大小设计是不同的。尤其是16位系统演变成32位系统和32位系统演变成64位系统,差异尤为明显。编译器为32位系统一般定义int为4字节,long同样为4字节。对于64位系统,long会提升为64位以与寄存器长度一致。
int类型的长度为什么不统一?
以C语言为例,它为了支持不同硬件平台,在计算机早期,硬件资源包括内存资源非常紧张,C语言标准不能直接规定int类型就是16位或者32位,这样会造成其它平台不能运行。故,标准做了取舍,不规定int类型的确切长度,但规定了与它相关的整型类型长度的大小关系,以此既支持不同平台,又避免不同平台带来类型长度出现long比int还小的混乱。但,不得不说,在不同平台、不同编译器下,C语言类型长度产生的问题一直存在。
- Swift/Go/Rust都有通用整型和确定长度的整型两种,据情况选择。
- 仓颉明确区分出Int32和Int64类型。
int类型和硬件寄存器有多统一?
Intel i386 32位设计的硬体,默认的数据寄存器、地址寄存器都是32位,即一次数据操作或者地址访问以32位为最优。C语言程序为了更好适应这种情况,大部分32位编译器都将int类型设计成4字节。这样,一个int就直接对应寄存器EAX或EBX的长度,资源使用上不会出现浪费。
了解更多:数据类型长度是编译器决定的?
编译器可以设定int和long的长度吗?
以long为例,虽然大部分64位C语言编译器long长度是8,依然有选项可以将long的长度设定为4.
- gcc -m32选项可以让GCC生成32位目标代码,sizeof(int)和sizeof(long)也就变成4.
- 需注意,gcc -m64选项可以让GCC生成64位目标代码,sizeof(int)依然保持4.
- man gcc看到形如-mint64, -mlong32之类的设定,值得注意的是:在某些GCC版本很可能不支持,不能认为这些选项一定有效!
若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。