我正在阅读有关System V AMD64呼叫约定的内容。它有一个部分,它在类中对函数的参数进行分类,其中一些是INTEGER,SSE,SSEUP,NO_CLASS,MEMORY等。
我无法理解它如何对聚合类型(即结构,联合和数组)进行分类。以下是对这些规则进行分类所遵循的规则。
规则:
如果对象的大小大于8个八位字节,或者它包含未对齐的字段,则它具有类MEMORY 12。
如果C ++对象具有非平凡的复制构造函数或非平凡的析构函数13,则它通过不可见的引用传递(该对象在参数列表中被具有类INTEGER的指针替换)14
如果聚合体的大小超过单个八字节,则每个都单独分类。每个八字节都被初始化为NO_CLASS类。
对象的每个字段都是递归分类的,因此始终考虑两个字段。结果类是根据八字节中的字段类计算的:
然后完成合并后清理:
我的问题在于理解规则3,4,5以及它们如何相互适用。
以下是一个例子,这些规则如何适用于B?
struct A{
int a;
long b;
char c;
};
struct B{
char a;
A b;
short* c;
};
我对它的看法是:
首先,sizeof(B) < 64
和我假设的字段布局正确对齐。因此,规则1不适用于此。
其次,规则2也不适用。
然而,在这里,对我来说是令人困惑的部分,此时,我理解它的方式,规则3,4都可以应用。所以有两条路径:
第一条路径是遵循规则3.规则3可以应用于sizeof(B) > 8
,因此它告诉我将B对象分解为它所组成的所有八字节。 (再次假设适当的对齐)我看到B.a和B.c有5个八字节,A和A的每个字段有3个。现在规则说每个8字节被初始化为NO_CLASS。但现在要找出B级的下一步是什么?我是否参考规则5?
另一方面,另一条路径是遵循并应用规则4.我理解规则4的方式说,首先找出你的结构的每个字段的类,并通过规则4的子规则扣除类整个结构。 但这里规则中有点奇怪的部分就是说
根据八字节
中字段的类别
那里有八字节是什么意思?这是否意味着规则4仅适用于八字节对象?它不适用于任何种类的对象结构吗?它是否可能应用于规则3的结果“对象”?
最后规则5发挥作用了吗?