【发布时间】:2015-02-12 13:22:02
【问题描述】:
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;
}
我用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
(&a - 2) 的内存位置似乎根本没有被使用。我在int a 和int b 的声明之间插入了以下代码:
*(&a - 2) = -1234;
这稍后将打印-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
使用g++ program.cpp 编译。版本:
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
当我将程序移植到 C 时,行为相同。一切都在 64 位 Linux Mint 17.1 上运行。谁能解释一下clang浪费4字节内存是否有更大的目的?
【问题讨论】:
-
你打印出实际的内存地址了吗?我的猜测是 8Byte 对齐允许更有效的参数传递或防止结构被拆分为两个缓存行(64 字节对齐)。至于与 g++ 的比较:两者都在 8 字节边界对齐结构,但在未优化模式下,clang 编译器更严格地遵循您的数据布局。正如你所做的是(据我所知)UB,这两种实现都是正确的,如果你不打开优化,也没有理由“抱怨”浪费。
标签: c++ pointers struct stack overhead