【发布时间】:2020-09-27 15:46:34
【问题描述】:
我试图深入了解结构和类填充,因此我设计了一个我认为比我在有关该主题的教程中找到的许多示例更具挑战性的示例。我用 g++ 在 x64 机器上编译它,没有启用任何代码优化。我的代码如下:
class Example
{
private:
long double foobar; // 10 bytes + 6 padded bytes as double follows
double barfoo; // 8 bytes + 8 padded bytes
static float barbar; // didn't count as it's a static member
float *fooputs; // 8 bytes + 8 padded bytes
int footsa; // 4 bytes, stored in the padded portion of float
char foo; // 1 byte, stored in the padded portion of float
public:
int function1(int foo) { return 1; }
void function2(int bar) { foobar = bar; }
};
int main()
{
std::cout << sizeof(Example) << std::endl; // 48 bytes
return 0;
}
虽然我看到Example 的大小是 48 字节,但我希望它是 37 字节。我的期望的论证如下:
-
foobar需要 10 个字节。正如double之后的内容,还需要 6 个字节进行填充。 -
barfoo需要 8 个字节,因为它是double。不需要填充,如mod(16,8) == 0 -
*fooputs需要 8 个字节,因为它是 x64 架构中的指针。不需要填充,如mod(24,8) == 0 -
footsa需要 4 个字节作为 int。不需要填充,如mod(32,4) == 0 -
foo需要 1 个字节作为字符。无需填充。
由于结果与预期不同,我试图通过注释 in 和 out 类成员来了解 C++ 如何将 Example 的大小评估为 48 字节。因此,除了foobar 的论证之外,我还假设了我在我的内联 cmets 中为每个成员编写的理由。
谁能解释一下如何将大小评估为 48 字节以及我的理由是否正确?
【问题讨论】:
-
看看为什么 37 的大小会不好:stackoverflow.com/questions/58435348/…
-
代码中的 cmets 建议的总和是 45,而不是 37。
-
@DanielLangr 你能详细说明 sizeof 完成的“最终填充”吗?
-
我数了 48 个字节。你的cmets是正确的。
long double+double+float*= 16 + 16 + 16 = 48。(我忽略了所有有填充空间的变量。) -
long doublex64 上不是 8 字节吗? 80 位格式适用于 32 位模式下的 x87; x64 使用 SSE2。