【问题标题】:Regarding integer memory allocation关于整数内存分配
【发布时间】:2012-09-30 14:16:29
【问题描述】:
如果分配给整数的内存在任何语言中都有限制(比如 C 中的 2 个字节或 4 个字节或 8 个字节)。使用 32 位或 64 位编译器在 32 位或 64 位机器上编译代码有什么关系。如果这真的是微不足道的问题,请原谅我。但请留下答案。
【问题讨论】:
标签:
c
unix
integer
32bit-64bit
biginteger
【解决方案1】:
如果您查看this page,您可以看到C 中的基本类型具有一定的保证最小大小。所以,你不会找到一个兼容的 C 实现,其中int 是 2 位,它必须至少是 16。
平台之间的差异使porting 软件经常成为有趣的挑战。
如果您的代码假设关于基本数据类型的事情不能保证为真(例如,执行以下操作的代码:int x = 0xfeedf00d;),那么该代码将不会便携的。当在与假设不匹配的平台上编译时,它将以各种通常难以预测的方式崩溃。例如,在 int 为 16 位的平台上,上述代码会将 x 设置为与程序员预期不同的值。
【解决方案2】:
如果您使用的是固定大小的整数类型(如 int8_t 或 int16_t),那么您的目标是 32 位还是 64 位平台并不重要。
其中一件重要的事情是指针的大小。面向 32 位架构时,所有指针都是 32 位,面向 64 位架构时,所有指针都是 64 位。
过去,将指针值存储在int 中是相当普遍的,尽管出于可移植性的原因,这种做法已变得非常不受欢迎,而 32/64 位的情况就是一个很好的例子。如果您将指针存储在 int 中,那么您的代码将在 64 位架构上调用未定义的行为,因为您截断了指针。当您要提取指针时,您可能会取消引用它可能会崩溃,或者(更糟糕的是)继续处理无效数据。
【解决方案3】:
在大多数情况下,字长会影响性能和堆栈使用。对于给定的体系结构,使用任何字长都是最快的。如果您定义两个 32 位整数,一个接一个,在 64 位机器上,一个将在字边界上,而另一个则不在。将字边界上的内容放入寄存器所需的处理比不在字边界上的内容要少。另一方面,如果您在 32 位机器上定义了一个 64 位整数,则需要两次提取来获取这两个字,并进行一些时髦的寄存器操作来对其执行整数运算。最后一部分与堆栈有关。堆栈总是由单词组成。如果机器的字长为 32 位,堆栈将是 32 位值的堆栈,而在 64 位机器上它们是 64 位值。并不是说你真的很在意,但是一个 32 位整数将被放在堆栈上的一个 64 位字中,并且一个 64 位值,除非你将一个指向该值的指针压入堆栈,否则它将占用堆栈上的两个字.
如果您在编译器中选择字对齐,它会自动将所有变量放在字边界上。这要快得多,但会占用更多空间。除非你真的很需要空间,否则你应该去表演。并不是说它对 CISC 架构有那么大的不同。在 RISC 上,它产生了巨大的影响。
这有帮助吗?
【解决方案4】:
您必须在 32 位和 64 位机器之间编译不同的可执行文件有几个原因 - int 的大小可能不是一个因素,或者它可能是一个因素,因为 C 标准只定义了最小值和相对大小 -据我所知,int 没有最大大小(只要它不超过 long)。
指针的大小是一个主要区别。编译器和链接器在 32 位和 64 位进程地址空间之间产生不同的可执行文件布局。运行时库不同,动态链接库(UNIX 上的共享对象)必须共享相同大小的指针,否则它们无法与进程的其余部分交互。
为什么使用 64 位? 64 位比 32 位有什么优势?主要优点是指针的最大大小,因此是进程地址空间。在 32 位上是 4GB,在 64 位上是 16EB(大约 16,000 TB)。