如何确定C ++类的大小? [英] How is the size of a C++ class determined?
问题描述
摘要:编译器如何在编译期间静态确定C ++类的大小?
Summary: How does the compiler statically determine the size of a C++ class during compilation?
:
Details:
我试图理解一个规则是用来确定一个类将使用多少内存,以及如何对齐内存。
I'm trying to understand what the rules are for determining how much memory a class will use, and also how the memory will be aligned.
例如下面的代码声明了4个类。前2个都是16字节。但是3是48字节,尽管它包含与第一个2相同的数据成员。虽然第四个类有与第三个相同的数据成员,只是在不同的顺序,但它是32字节。
For example the following code declares 4 classes. The first 2 are each 16 bytes. But the 3 is 48 bytes, even though it contains the same data members as the first 2. While the fourth class has the same data members as the third, just in a different order, but it is 32 bytes.
#include <xmmintrin.h>
#include <stdio.h>
class TestClass1 {
__m128i vect;
};
class TestClass2 {
char buf[8];
char buf2[8];
};
class TestClass3 {
char buf[8];
__m128i vect;
char buf2[8];
};
class TestClass4 {
char buf[8];
char buf2[8];
__m128i vect;
};
TestClass1 *ptr1;
TestClass2 *ptr2;
TestClass3 *ptr3;
TestClass4 *ptr4;
int main() {
ptr1 = new TestClass1();
ptr2 = new TestClass2();
ptr3 = new TestClass3();
ptr4 = new TestClass4();
printf("sizeof TestClass1 is: %lu\t TestClass2 is: %lu\t TestClass3 is: %lu\t TestClass4 is: %lu\n", sizeof(*ptr1), sizeof(*ptr2), sizeof(*ptr3), sizeof(*ptr4));
return 0;
}
我知道答案与数据成员的对齐有关班上。但我想弄清楚这些规则是什么以及它们如何在编译步骤中应用,因为我有一个类有一个 __ m128i
数据成员,但数据成员是不是16字节对齐,当编译器使用 movaps
生成代码以访问数据时,会导致segfault。
I know that the answer has something to do with alignment of the data members of the class. But I am trying to understand exactly what these rules are and how they get applied during the compilation steps because I have a class that has a __m128i
data member, but the data member is not 16-byte aligned and this results in a segfault when the compiler generates code using movaps
to access the data.
推荐答案
对于POD(普通旧数据),规则通常是:
For POD (plain old data), the rules are typically:
- 结构具有一些大小s和一些对齐要求a。
- 编译器开始时大小S设置为零,对齐要求A设置为一(字节)。
- 编译器按顺序处理结构中的每个成员:
- Each member in the structure has some size s and some alignment requirement a.
- The compiler starts with a size S set to zero and an alignment requirement A set to one (byte).
- The compiler processes each member in the structure in order:
- 考虑成员的对齐要求a。如果S当前不是a的倍数,那么只需要添加足够的字节S,使得它是a的倍数。这决定了成员将去哪里;它将从结构的开始(对于S的当前值)偏移S处。
- 将A设置为A和a的最小公倍数。
- 将S添加到S,为成员预留空间。
当上述操作完成后,结构的大小是S的值。
The size of the structure is the value of S when the above is done.
此外:
- 如果任何成员是数组,其大小是元素数乘以每个元素的大小,其对齐要求是元素的对齐要求。
- 如果任何成员是结构,则其大小和对齐要求按上述计算。
- 如果任何成员是联合:
- If any member is an array, its size is the number of elements multiplied by the size of each element, and its alignment requirement is the alignment requirement of an element.
- If any member is a structure, its size and alignment requirement are calculated as above.
- If any member is a union:
- 将S设置为最大成员的大小。
- 将A设置为所有成员对齐的最小公倍数。
- 如果S不是A的倍数,只需将S加到S的倍数,使其成为A的倍数。
考虑您的 TestClass3
:
- <0> A从$ 1开始。
-
char buf [8]
需要8个字节和对齐方式1,所以S增加8到8,并且A保持为1. -
__ m128i vect
需要16个字节和对齐16.首先,S必须增加到16给出正确的对齐方式。然后A必须增加到16.那么S必须增加16才能为vect
增加空间,因此S现在为32. -
char buf2 [8]
需要8个字节和对齐方式1,所以S增加8到24,A保持为16。 - 最后,S是24,它不是A(16)的倍数,因此S必须增加8到32。
- S starts at 0 and A starts at 1.
char buf[8]
requires 8 bytes and alignment 1, so S is increased by 8 to 8, and A remains 1.__m128i vect
requires 16 bytes and alignment 16. First, S must be increased to 16 to give the right alignment. Then A must be increased to 16. Then S must be increased by 16 to make space forvect
, so S is now 32.char buf2[8]
requires 8 bytes and alignment 1, so S is increased by 8 to 24, and A remains 16.- At the end, S is 24, which is not a multiple of A (16), so S must be increased by 8 to 32.
因此 TestClass3
的大小为32个字节。
So the size of TestClass3
is 32 bytes.
对于基本类型( int
, double
等),对齐要求是依赖于实现的,并且在很大程度上由硬件确定。在许多处理器上,加载和存储数据时具有特定对齐方式(通常是在存储器中的地址是其大小的倍数时)更快。除此之外,上述规则大部分遵循逻辑;他们将每个成员放在必须满足对齐要求的位置,而不使用比必要的更多空间。
For elementary types (int
, double
, et cetera), the alignment requirements are implementation dependent and are largely determined by the hardware. On many processors, it is faster to load and store data when it has a certain alignment (usually when its address in memory is a multiple of its size). Beyond this, the rules above follow largely from logic; they put each member where it must be to satisfy alignment requirements without using more space than necessary.
这篇关于如何确定C ++类的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!