这很大程度上取决于使用情况。
- 您通常可以强制编译器优化空间。
- 对象在对齐到其大小的倍数的内存边界时,可以更优化地访问(在大多数体系结构上)。
因此,编译器可能会注入空间以获得更好的对齐。
这通常发生在需要将不同大小的对象并排放置时。
- 编译器不允许重新排列结构中变量的顺序(如果它们位于同一私有/公共/受保护部分中)。
- 我认为本地堆栈帧中的变量排序没有任何要求。因此,编译器应该能够以最佳方式打包局部变量并以最佳方式使用所有可用空间(甚至可能为 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.
};
为了举例,我们假设对于某台现代计算机:
如果我们假设在普通标准架构机器上使用像 clang 或 g++ 这样的现代优秀编译器。即使我们假设没有优化速度。
short 真的会占用更少的内存吗
是的。现代编译器将尽可能多地打包对象,并且可能只使用所需的内存。注意:默认情况下,大多数编译器都会针对速度进行优化,因此将保持最佳的速度对齐方式,因此如果必须的话会填充(如果它们无法重新排序的结构中的对象具有不同的大小)。
还是只存储在 WORD 的前半部分,后半部分未使用内存?
除非有编译器必须维护的某些要求,否则不太可能。类似于结构的顺序。
C/C++ 编译器是否会尝试将两个或多个较小的变量打包到一个 WORD 中
是的。每时每刻。默认值通常是。 1 优化速度。 2 优化大小(并不总是相互排斥)。您还可以强制现代编译器在没有填充的情况下针对空间和包结构进行优化。
还是会一直浪费这个空间?
不太可能。