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 a和int 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字节内存是否有更大的目的?
您运行的测试与结构无关,与堆栈有关。从随机堆栈内存位置开始读取是未定义的行为,编译器完全有权对它们执行任何操作。如果没有优化,编译器显然不会费心有效地使用它们。没有人关心在没有优化的情况下丢失几个字节。
此外,结构和类布局是由 GCC 和 Clang 通用的标准定义的,因此我向您保证它们在 Linux 上是相同的(模错误)。
本质上,您假设编译器在堆栈上以精确的顺序放置局部变量,而没有其他任何东西,但绝对没有理由相信这是真的。编译器没有义务以任何方式布置堆栈。