use*_*919 6 c++ class compiler-options
我正在使用fdump-class-hierarchy编译器选项,但我不知道如何理解输出."大小","对齐","基本大小"和"碱基对齐"是什么意思,以及这些是如何计算的?谢谢!
当代码是:
class A
{
public:
private:
double m_nothing;
int m_number;
};
Run Code Online (Sandbox Code Playgroud)
输出是:
Class A
size=16 align=8
base size=16 base align=8
A (0x406c690) 0
Run Code Online (Sandbox Code Playgroud)
但是,如果我稍微改变一下课程:
class A
{
public:
private:
int m_number;
double m_nothing;
};
Run Code Online (Sandbox Code Playgroud)
输出将是:
Class A
size=16 align=8
base size=12 base align=8
A (0x406c690) 0
Run Code Online (Sandbox Code Playgroud)
cel*_*chk 14
的size和align为完成型时是尺寸和类的对准.也就是说,如果您创建完整类型是该类型的对象(比如定义该类型的变量,或者使用该类型new).
大小只是它占用的字节数.因此,size=16当用作完整类型时,它总是占用16个字节.
对齐告诉您对象的放置位置:align=8表示对象的地址必须是8的整数倍.
的base size和base align给出的情况下,所述类被用作基类大小和对齐.它们不同的原因是C++标准允许对象在用作基类时使用较少的填充.
因此,让我们专门看一下你的例子(我假设你实际上在第一种情况下有int之前double).我也省略了public,并private因为在这里他们不会改变任何东西(如果你有两个公共或私有数据的成员,他们可能在原则上改变一些东西,但我不知道是否有任何编译器会利用这一点).我也猜的大小和排列int及double(实际上我假设值是相当普遍的选择,并解释你得到的值).
所以在第一种情况下(我假设)你有
class A
{
int m_number;
double m_nothing;
};
Run Code Online (Sandbox Code Playgroud)
现在int有尺寸和对齐4,double有尺寸和对齐8.
所以让我们完成编译器的工作并构建我们的类.
首先,我们有m_number,占用4个字节.我们必须按照给定的顺序放置成员,所以m_number在开始时A:
iiii
Run Code Online (Sandbox Code Playgroud)
到目前为止,我们的大小为4(int的四个字节)和对齐4(因为int具有对齐4).但是现在我们必须添加一个double(大小和对齐8).因为直接在int之后,我们在(相对)地址4,我们没有正确对齐double,所以我们必须添加4个填充字节(我将标记*)以获得8的倍数.因此我们得到我们的课程:
iiii****dddddddd
Run Code Online (Sandbox Code Playgroud)
现在,如果该类被用作基类,我们就完成了.因此我们habe base size=16和base align=8(我们需要8的对齐才能正确对齐).
对于完整的对象,还有另一个考虑因素:标准要求在数组中,对象彼此跟随,两者之间没有间隙.也就是说,对象之后的第一个字节必须正确对齐下一个对象.这最终意味着整个对象的大小必须是其对齐的倍数.
现在我们发现的对象布局已经满足了这个要求.因此,对于完整的对象,我们也可以不改变地使用它.因此,我们得到size=16和align=8为完整的对象.
现在考虑订单颠倒的情况:
class A
{
double m_nothing;
int m_number;
};
Run Code Online (Sandbox Code Playgroud)
现在我们必须从double:
dddddddd
Run Code Online (Sandbox Code Playgroud)
接下来,我们要添加int.事实证明,下一个空闲位置已经正确对齐int,因此我们可以添加它:
ddddddddiiii
Run Code Online (Sandbox Code Playgroud)
现在我们已经准备好了作为基础对象使用.如您所见,我们只需要12个字节base size=12.当然,double为了正确对齐,对象必须再次从8的倍数开始.因此我们有base align=8.
然而,对于作为完整对象的sue,我们现在发现下一个地址将位于第12位,该位置未正确对齐该double成员.因此,我们必须添加填充字节,直到我们再次到达正确对齐的地址:
ddddddddiiii****
Run Code Online (Sandbox Code Playgroud)
如您所见,现在我们需要16个字节size=16.我们仍然有align=8两倍.
请注意,对齐要求可能会显着影响类的大小.例如,考虑以下两种类型:
struct S1
{
char c1;
double d1;
char c2;
double d2;
char c3;
};
struct S2
{
double d1;
double d2;
char c1;
char c2;
char c3;
};
Run Code Online (Sandbox Code Playgroud)
虽然两者都包含相同的成员,S1但是上面的大小和对齐将具有40的总(非基础)大小,而总大小S2将仅为24.实际上,类型的对象S1将作为完整对象看起来像
c*******ddddddddc*******ddddddddc*******
Run Code Online (Sandbox Code Playgroud)
而类型的那些S2看起来像
ddddddddddddddddccc*****
Run Code Online (Sandbox Code Playgroud)
因此,底线是具有最高对齐要求的成员应始终排在第一位.
另请注意,sizeof返回完整对象的大小,即类层次结构转储调用的内容size.
| 归档时间: |
|
| 查看次数: |
2070 次 |
| 最近记录: |