我知道这都是特定于实现的,但为了举例,让我们假设对于某台现代计算机:
int
占据整个 WORD
short
占据半个WORD
short 实际上会占用更少的内存,还是只是存储在 WORD 的前半部分,后半部分未使用内存? C/C++ 编译器是否会尝试将两个或多个较小的变量打包到一个 WORD 中,还是会一直浪费这个空间?
最佳答案
这在很大程度上取决于使用情况。
- 您通常可以强制编译器优化空间。
- 当对象与大小倍数的内存边界对齐时,可以更优化地访问对象(在大多数架构上)。
因此,编译器可能会注入(inject)空间以获得更好的对齐。
当需要将不同大小的对象彼此并排放置时,通常会发生这种情况。 - 编译器不允许重新排列结构中变量的顺序(如果它们位于同一私有(private)/公共(public)/ protected 部分)。
- 我不认为本地堆栈帧中的变量排序有任何要求。因此,编译器应该能够以最佳方式打包局部变量并以最佳方式使用所有可用空间(甚至可能为 POD 变量重新使用空间,或者如果可以将空间保留在寄存器中,则从不使用空间)。
但是如果您有一个使用相同大小对象的结构。
struct X
{
short var1;
short var2;
}
那么上述结构中很可能没有填充(不能保证,但很可能没有填充)。
由于上面的第 3 点:如果您想帮助您的编译器以最佳方式打包结构,那么它肯定会使编译器更容易地按从大到小的顺序对成员进行排序,因为这使得打包无需填充变得更容易(但是标准对填充没有强加任何要求)。
// if we assume sizeof(int) == 8
struct Y
{
char x; // 1 byte;
// Compiler will (prob) insert 7 bytes of padding here.
// to make sure that y is on an 8 byte boundry
// for most effecient reads.
int y;
char z; // 1 byte
// Compiler will (prob) insert 7 bytes of padding here.
// to make sure that the whole structure has a size
// that is a multiple of 8 (the largest object)
// This allows for optimal packing of arrays of type
// Y.
};
如果你这样安排对象,编译器仍然可以实现最佳打包和快速访问:
struct Y
{
int y;
char x;
char z;
// probably add 6 bytes of padding.
// So that we get optimal access to objects in an array.
};
for the sake of example let's assume that for a certain modern computer:
如果我们假设在普通标准架构机器上有一个像 clang 或 g++ 这样的现代良好编译器。即使我们假设不优化速度。
Will the short actually take up less memory
是的。现代编译器将尽可能多地打包对象,并且可能只使用所需的内存。注意:大多数编译器默认都会针对速度进行优化,因此会保持速度的最佳对齐,因此如果必须的话会进行填充(如果它们无法重新排序的结构中的对象具有不同的大小)。
or will it just be stored in the first half of a WORD with unused memory in the second half?
不太可能,除非编译器必须满足某些要求。就像结构的顺序。
Will a C/C++ compiler ever try to pack two or more smaller variables into a single WORD
是的。每时每刻。通常默认是。 1 优化速度。 2 优化大小(并不总是相互排斥)。您还可以强制现代编译器优化空间和包结构,而无需填充。
or will this space always be wasted?
不太可能。
关于c++ - WORD 大小和 C/C++ 变量 - 较小的 Int 大小实际上使用较少的内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61500634/