Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么32位和64位程序的结构大小不同?_C++_C - Fatal编程技术网

C++ 为什么32位和64位程序的结构大小不同?

C++ 为什么32位和64位程序的结构大小不同?,c++,c,C++,C,下面是一个简单的C程序: #include <stdio.h> typedef struct { char a; double b; } A; int main(void) { printf("sizeof(A) is %d bytes\n", sizeof(A)); return 0; } 我知道结构记忆模式应该是: ____________________________ |a|3 padding| b | ———

下面是一个简单的
C
程序:

#include <stdio.h>

typedef struct
{
    char a;
    double b;
} A;
int main(void) {
    printf("sizeof(A) is %d bytes\n", sizeof(A));
    return 0;
}
我知道结构记忆模式应该是:

 ____________________________
|a|3 padding| b              |
 ————————————————————————————
 ____________________________________
|a|7 padding        | b              |
 ____________________________________
但是当我把它编译成64位程序时,输出是:

sizeof(A) is 12 bytes
sizeof(A) is 16 bytes
因此,结构记忆模型应为:

 ____________________________
|a|3 padding| b              |
 ————————————————————————————
 ____________________________________
|a|7 padding        | b              |
 ____________________________________

就我个人而言,我认为无论程序是
32位
还是
64位
,结构的大小都应该是
16
字节(因为
char
的长度是
1
字节,而
double
的对齐长度是
8
字节)。为什么
32位
程序中的大小是
12
字节?

由实现定义


最后,这取决于CPU指令在访问内存时的限制。编译器通常会首先选择速度最快的布局,其次是内存使用效率最高的布局。

深入研究这个问题后,我想自己回答这个问题

我的操作系统是Solaris,这个问题发生在X86上(他的评论是正确的)。当我在
SPARC
上测试它时,32位和64位程序输出“
sizeof(A)是16字节

我认为原因是:

  • 在X86上,访问未对齐的数据不会导致程序 向下,它只会影响性能。对于32位
  • 程序, CPU指令一次可以访问内存的
    4字节
    ,因此 访问
    8字节双字节
    将使用
    2
    指令,无需 以对齐数据。但是对于
    64位
    程序,CPU指令 一次可以访问内存的
    8字节
    ,因此将
    8字节双字节
    将仅使用
    1
    指令获取数据,这将提高性能 表演
  • Ox
    SPARC
    ,数据需要严格对齐,否则会导致 “
    总线错误
    ”。因此,在
    double
    使其与
    8字节
    地址对齐的数据

  • 简单地说,这个问题取决于
    CPU
    ,正如已经回答的那样。

    在Intel CPU上,32位和64位机器,“SIMD”变量的浮点指令在一条机器指令上读/写16字节(2倍)或8字节(单倍)。这些是处理浮点最常见的指令。这都是速度的问题:

    可以通过“对齐读取指令”或“未对齐读取指令”读取单个数据项。确保对齐版本更快。未对齐指令必须处理数据在两个缓存线甚至两个不同内存页之间分割的复杂情况。 此外,CPU针对某些指令进行了优化,即对齐的指令。 经过优化,读取1字节数据比读取16个对齐字节更耗时。8088(MOV AL/MOV AH等)的古老1字节指令没有经过硬件优化


    编译器编写者必须选择密集代码或快速代码。在过去,我的电脑有16 KB的内存,但内存不足。稍后,可以准确地指示编译器如何对齐结构成员。当64位CPU问世时,内存足够便宜,结构大小变成了16字节的倍数,每个结构成员根据其类型在其自然边界上对齐:短路的偶数地址,整数和浮点的mod(4,0),整数和浮点的mod(8,0),整数64和双精度的mod(8,0),整数128的mod(16,0),模式(32,0)对于_mm256

    ,编译器可以按照C规范将任意数量的填充字节放在结构成员之后。在32位平台上,最大对齐为4字节。根本没有8字节对齐的类型。8字节值需要作为两个字存储在内存中,如果是64位整数类型,则需要存储在两个寄存器中。因此,没有必要(也没有任何性能改进)将数据与8字节边界对齐。@TheParamagneticCroissant:错误。看见Windows在8字节边界上对齐双倍,即使在32位计算机上也是如此。@ParamagneticCroissant:在32位Intel平台上,您是对的。在几乎任何其他平台(SPARC、PowerPC等)上,您都是不正确的,像
    double
    这样的8字节类型需要在8字节边界上对齐。我们可以从这个问题推断OP实际上使用的是英特尔。@JonathanLeffler是的,对。我希望我能编辑我的评论来修改它。32/64位编译器在32位模式下更倾向于使用内存是合理的。毕竟,程序员选择以32位模式编译可能是有原因的。