C 在结构中使用长双人床时的对齐

C 在结构中使用长双人床时的对齐,c,struct,padding,memory-alignment,long-double,C,Struct,Padding,Memory Alignment,Long Double,我知道,一般来说,结构实例将与其最宽的标量成员对齐。我声明了一个结构,其成员为longdouble数据类型 struct try { char a; long double b; }; struct try obj; 当我试图检查sizeof(obj)时,结果显示为16。我的编译器假定长双精度为12字节。所以我无法理解填充是如何在这里完成的,以及对齐是如何在结构中发生的。我假设对齐将基于长双精度,因为它是最宽的标量成员。所以char应该有11字节填充,结构变量的大小应该是24,

我知道,一般来说,结构实例将与其最宽的标量成员对齐。我声明了一个结构,其成员为
longdouble
数据类型

struct try
{
    char a;
    long double b;
};
struct try obj;


当我试图检查
sizeof(obj)
时,结果显示为
16
。我的编译器假定长双精度
12
字节。所以我无法理解填充是如何在这里完成的,以及对齐是如何在结构中发生的。我假设对齐将基于
长双精度
,因为它是最宽的标量成员。所以char应该有
11
字节填充,结构变量的大小应该是
24
,但输出是
16
。那么这里到底发生了什么?。我正在使用
64位处理器。

首先,您的编译器正在创建32位输出,即使您有64位处理器。不管怎样,你假设事物需要对齐到一个与其大小相同的边界,这在一般情况下是不正确的。特别是,在您的例子中,
长双精度
s占用12个字节,但只需要与4字节边界对齐。同样,在单字节
char
之后,编译器插入3个字节的填充以达到4字节边界,然后插入12字节
长的双字节
。1+3+12是16,因此struct try的长度是16字节。

首先,即使您有64位处理器,编译器也会创建32位输出。不管怎样,你假设事物需要对齐到一个与其大小相同的边界,这在一般情况下是不正确的。特别是,在您的例子中,
长双精度
s占用12个字节,但只需要与4字节边界对齐。同样,在单字节
char
之后,编译器插入3个字节的填充以达到4字节边界,然后插入12字节
长的双字节
。1+3+12是16,所以
struct try
是16字节长。

你把大小和对齐弄混了吗?你的确切意思是什么?显然对齐是在
int
32大小上:一个
a
的int是4字节加上12,长浮点等于16。一个结构并不总是需要与其大小对齐。例如,
char[100]
的大小为100,但对齐方式为1。@JosephSible,变量将从int边界开始。您是否混淆了大小和对齐方式?您的确切意思是什么?显然对齐方式是在
int
32大小上:一个int代表
a
是4字节加上12,长浮点等于16。一个结构并不总是必须与其大小对齐。例如,
char[100]
的大小为100,但对齐方式为1。@JosephSible,变量将从int边界开始。关于填充和对齐,我将在本文后面介绍。:。每当我使用大小小于或等于8字节的数据类型时,该规则都能正常工作(所有结构元素都与最宽的标量成员对齐)。但您说过长双精度只需要与4字节边界对齐。这背后的原因是什么?我没有在上面的文章中读到任何这样的规则。请您更深入地解释一下边界对齐是如何发生的,尤其是当数据类型的大小超过8字节时。这与我写的内容并不矛盾。结构中有两个标量成员:
char
,对齐方式为1;和
long double
,对齐方式为4。1和4的最宽值是4,您的结构确实有对齐4。但是正如我所说的
longdouble
在我的编译器中有12个字节。这就是我的全部问题。为什么要使用4个字节进行对齐。这背后一定有某种逻辑?如果我遗漏了什么,对不起?@Noshiii这正是i386 ABI所说的。在编译器中,请参阅什么是
\u Alignof(长双精度)
。是的,你说得对。但是请注意,它不是
alignof
(来自
stdalign.h
)就是
\u alignof
(内置)<代码>\u alignof
不存在。我在下面这篇文章中介绍填充和对齐。:。每当我使用大小小于或等于8字节的数据类型时,该规则都能正常工作(所有结构元素都与最宽的标量成员对齐)。但您说过长双精度只需要与4字节边界对齐。这背后的原因是什么?我没有在上面的文章中读到任何这样的规则。请您更深入地解释一下边界对齐是如何发生的,尤其是当数据类型的大小超过8字节时。这与我写的内容并不矛盾。结构中有两个标量成员:
char
,对齐方式为1;和
long double
,对齐方式为4。1和4的最宽值是4,您的结构确实有对齐4。但是正如我所说的
longdouble
在我的编译器中有12个字节。这就是我的全部问题。为什么要使用4个字节进行对齐。这背后一定有某种逻辑?如果我遗漏了什么,对不起?@Noshiii这正是i386 ABI所说的。在编译器中,请参阅什么是
\u Alignof(长双精度)
。是的,你说得对。但是请注意,它不是
alignof
(来自
stdalign.h
)就是
\u alignof
(内置)<代码>\u alignof
不存在。