Vis*_*Lia 44 c c++ linux compiler-construction operating-system
谁决定任何数据类型或结构的大小(取决于32位还是64位)?编译器还是处理器?例如,sizeof(int)32位系统是4个字节,而64位系统是8个字节.
我还读到sizeof(int)使用32位和64位编译器编译时的4个字节.
假设我的CPU能为64位应用程序,谁在决定数据的大小起到主要作用同时运行32位和该编译器或处理器?
Pro*_*ica 43
它最终是编译器.无论CPU处理效率最高,编译器实现者都可以决定模拟他们认为合适的整数大小.也就是说,编写C(和C++)标准,编译器实现者可以自由选择最快,最有效的方法.对于许多编译器,实现者选择将int保持为32位,尽管CPU本身非常有效地处理64位整数.
我认为这部分是为了增加对32位机器最常见并且期望int为32位而不再是int的程序的可移植性.(也可能是,正如用户user3386109指出的那样,32位数据是首选,因为它占用的空间更少,因此可以更快地访问.)
因此,如果您想确保获得64位整数,则使用int64_t而不是int声明您的变量.如果你知道你的值适合32位或者你不关心大小,你int可以让编译器选择最有效的表示.
至于其他数据类型,例如struct,它们由基类型组成int.
Art*_*Art 26
它不是CPU,也不是编译器,也不是操作系统.这三个是同时进行的.
编译器不能只是搞砸了.它必须遵守操作系统提供的正确的ABI [1].如果操作系统提供的结构和系统调用具有某些大小和对齐要求的类型,那么除非编译器开发人员想要为操作系统提供的所有内容重新实现包装函数,否则编译器实际上无法自行构建自己的实际情况.然后操作系统的ABI不能完全组成,它必须做可以在CPU上合理完成的事情.通常,一个操作系统的ABI与同一CPU上其他操作系统的其他ABI非常相似,因为它更容易重用他们所做的工作(在编译器等).
如果计算机同时支持32位和64位代码,则操作系统仍需要完成工作以支持在两种模式下运行程序(因为系统必须提供两种不同的ABI).有些操作系统没有这样做,而有些操作系统则没有选择.
[1] ABI代表应用程序二进制接口.它是程序如何与操作系统交互的一组规则.它定义了程序如何存储在磁盘上以便操作系统可以运行,如何进行系统调用,如何与库链接等等.但是为了能够链接到库,例如,您的程序和库必须同意关于如何在程序和库之间进行函数调用(反之亦然),并且为了能够进行函数调用,程序和库必须具有相同的堆栈布局,寄存器用法,函数调用约定等概念.对于函数调用,您需要就参数的含义达成一致,包括类型的大小,对齐和签名.
严格地说,100%完全是编译器决定sizeof(int)的值.它不是系统和编译器的组合.它只是编译器(和C/C++语言规范).
如果您开发iPad或iPhone应用程序,则可以在Mac上运行编译器.Mac和iPhone/iPac使用不同的处理器.没有任何关于你的Mac告诉编译器应该在iPad上使用int的大小.
处理器设计者确定哪些寄存器和指令可用,有效访问的对齐规则是什么,内存地址有多大等等.
C标准设置了内置类型的最低要求."char"必须至少为8位,"short"和"int"必须至少为16位,"long"必须至少为32位,"long long"必须至少为64位.它还说"char"必须与程序可以解决的最小内存单元相等,并且必须保持标准类型的大小顺序.
其他标准也可能产生影响.例如,"单一Unix规范"的版本2表示int必须至少为32位.
最后,现有代码会产生影响.移植已经很难了,没有人想让它变得更难.
将操作系统和编译器移植到新CPU时,有人必须定义所谓的"C ABI".这定义了二进制代码如何相互通信,包括.
一般而言,一旦ABI被定义为CPU系列和OS的组合,它的变化不大(有时像"长双"变化这样的更模糊类型的大小).改变它会带来一堆破损,收益相对较小.
类似地,将操作系统移植到具有与现有操作系统类似特征的平台的那些通常会选择与移植到操作系统的先前平台相同的大小.
实际上,OS /编译器供应商通常会选择基本整数类型的几种大小组合之一.
64位处理器通常可以运行32位和64位二进制文件.通常,这是通过在操作系统中使用兼容层来处理的.因此,您的32位二进制文件使用与在32位系统上运行时相同的数据类型,然后兼容层会转换系统调用,以便64位操作系统可以处理它们.
| 归档时间: |
|
| 查看次数: |
4542 次 |
| 最近记录: |