clang 中的 C++ struct 内存开销?

byt*_*ude 5 c++ stack struct pointers overhead

在 clang 中是否有每个结构的内存开销?通常结构体的大小就是其所有成员的总大小。但在 clang 中似乎并非如此:

#include <iostream>
using namespace std;

struct Obj {
    int x;
    int y;
};

int main() {
    int a = 42;
    int b = 43;
    Obj obj = {100, 101};
    int c = 44;

    cout << *(&a - 0) << endl;  // 42
    cout << *(&a - 1) << endl;  // 43
    cout << *(&a - 2) << endl;  // On clang this prints garbage value instead of 101, how strange...
    cout << *(&a - 3) << endl;  // 101
    cout << *(&a - 4) << endl;  // 100
    cout << *(&a - 5) << endl;  // 44

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用 编译clang++ program.cpp,没有优化。版本:

Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix
Run Code Online (Sandbox Code Playgroud)

(&a - 2)似乎根本没有使用内存位置。我插入的声明之间下面的代码int aint b

*(&a - 2) = -1234;
Run Code Online (Sandbox Code Playgroud)

这稍后将在 上打印-1234而不是垃圾值*(&a - 2),表明 clang 在创建后没有写入这个值Obj obj,这让我想知道为什么 clang 首先保留它。

在 gcc 上这表现不同。首先,堆栈似乎在我机器上的 gcc 上朝着更高的内存地址增长。此外,gcc 自行将变量放在c之后b,所以它看起来像这样:

cout << *(&a + 0) << endl;  // 42
cout << *(&a + 1) << endl;  // 43
cout << *(&a + 2) << endl;  // 44 gcc moved c here even without optimization
cout << *(&a + 3) << endl;  // 100
cout << *(&a + 4) << endl;  // 101
Run Code Online (Sandbox Code Playgroud)

g++ program.cpp. 版本:

 g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Run Code Online (Sandbox Code Playgroud)

当我将程序移植到 C 时也是如此。一切都在 64 位 Linux Mint 17.1 上运行。有人可以解释一下clang浪费4字节内存是否有更大的目的?

Pup*_*ppy 2

您运行的测试与结构无关,与堆栈有关。从随机堆栈内存位置开始读取是未定义的行为,编译器完全有权对它们执行任何操作。如果没有优化,编译器显然不会费心有效地使用它们。没有人关心在没有优化的情况下丢失几个字节。

此外,结构和类布局是由 GCC 和 Clang 通用的标准定义的,因此我向您保证它们在 Linux 上是相同的(模错误)。

本质上,您假设编译器在堆栈上以精确的顺​​序放置局部变量,而没有其他任何东西,但绝对没有理由相信这是真的。编译器没有义务以任何方式布置堆栈。