当包含int64变量时,为什么struct size是8的倍数在32位系统中

时间:2011-02-18 15:16:47

标签: c struct sizeof

在C编程语言中我使用32位系统, 我有一个结构,这个结构大小是四的倍数。 但我看看Linker Map文件,大小是8的倍数 实施例

typedef struct _str
{
U64 var1,
U32 var2
} STR;

此结构的大小为16。 但是

typedef struct _str
{
U32 var1,
U32 var2,
U32 var3
} STR2;

STR2的大小为12。 我正在研究32位ARM微控制器。 我不知道为什么

4 个答案:

答案 0 :(得分:3)

填充第一个结构以使其在U64边界上对齐:它等同于

struct STR
{
    U64 var1;
    U32 var2;
    U8  pad[4]; /* sizeof(U64) - sizeof(U32) */
};

因此,当在结构STR []数组中使用时,每个U64都与ABI要求完全一致。

查看Procedure Call Standard for ARM Architecture,4.1基本数据类型。

答案 1 :(得分:1)

填充。

假设你有

typedef struct _str
{
U64 var1,
U32 var2
} STR;

STR s[2];

您的架构可能会要求s[0].var1s[1].var1位于U64的自然对齐位置,位于8字节边界。由于C不在数组元素之间放置填充,因此填充进入结构内部。

另一方面,

typedef struct _str
{
U32 var1,
U32 var2,
U32 var3
} STR2;

STR2 s2[2];

此处仅需要4字节对齐。

答案 2 :(得分:1)

结构的大小定义为具有最大对齐要求的成员的对齐的倍数。看起来U64的对齐要求即使在您平台上的32位模式下也是8字节。

以下代码:

#include <stdio.h>
#include <stdint.h>
int main() { printf("alignof(uint64_t) is %zu\n", __alignof(uint64_t)); }

在Linux x86_64上以32位和64位模式编译时生成相同的输出:

alignof(uint64_t) is 8

答案 3 :(得分:1)

一些背景知识,可以帮助您解决此类问题。

由于原始内存操作通常以8的倍数指定,编译器工程师决定内存数据结构的填充方案。

如果内存检索操作(内存 - >总线 - > cpu)将是16位(在假想的计算机上)块并且在结构中放置3 * 8位类型,编译器设计者可能会以及从2,16位内存填充32位结构,将进行检索操作以将结构拉入CPU缓存以进行CPU操作。

当然,您可以告诉编译器不要在异常情况下执行此操作,例如设计磁盘或网络协议,您可能希望空间有用。

在现实世界中,这些问题更为复杂,但决策源于通用有效使用硬件的最佳选择:D