您的位置:首页 > 移动开发 > Objective-C

Dumping a C++ object's memory layout with Clang

2015-12-13 09:26 405 查看
http://eli.thegreenplace.net/2012/12/17/dumping-a-c-objects-memory-layout-with-clang

When one wants to understand the memory layout of structures and classes, the C/C++ operators
sizeof and offsetof are very useful. However, when large C++ class hierarchies are involved, using these operators becomes tedious. Luckily, Clang has a very handly command-line flag to dump
object layouts in a useful manner. This flag is somewhat hidden since it's only accepted by the Clang front-end (the one you get when you pass
-cc1 to
clang) and not the gcc-compatible compiler driver (the one you get when simply executing
clang).

Consider this code, for example:

class Base {
protected:
int foo;
public:
int method(int p) {
return foo + p;
}
};

struct Point {
double cx, cy;
};

class Derived : public Base {
public:
int method(int p) {
return foo + bar + p;
}
protected:
int bar, baz;
Point a_point;
char c;
};

int main(int argc, char** argv) {
return sizeof(Derived);
}


To see the layout, run clang -cc1
-fdump-record-layouts myfile.cpp. It will produce a separate report for each class and struct defined, but the most interesting one is for
class Derived:

*** Dumping AST Record Layout
0 | class Derived
0 |   class Base (base)
0 |     int foo
4 |   int bar
8 |   int baz
16 |   struct Point a_point
16 |     double cx
24 |     double cy
|   [sizeof=16, dsize=16, align=8
|    nvsize=16, nvalign=8]

32 |   char c
| [sizeof=40, dsize=33, align=8
|  nvsize=33, nvalign=8]


(the above is the output of Clang 3.2 running on 64-bit Linux)

We can see the layout of Derived objects, with the offset of every field (including the fields coming from base classes) in the left-most column. Some additional information is printed in the bottom - for example, sizeof
- the total size, and dsize - data size without tail padding.

If we make method virtual in the
Base and Derived classes, the size of the virtual-table pointer is also accounted for:

*** Dumping AST Record Layout
0 | class Derived
0 |   class Base (primary base)
0 |     (Base vtable pointer)
0 |     (Base vftable pointer)
8 |     int foo
12 |   int bar
16 |   int baz
24 |   struct Point a_point
24 |     double cx
32 |     double cy
|   [sizeof=16, dsize=16, align=8
|    nvsize=16, nvalign=8]

40 |   char c
| [sizeof=48, dsize=41, align=8
|  nvsize=41, nvalign=8]


I'll wrap up with a tip about using clang
-cc1. Since this isn't the compiler driver, it won't go look for standard headers in the expected places, so using it on realistic source files can be a pain. The easiest way to do it, IMHO, is to run it on preprocessed source. How your source gets
preprocessed depends on your build process, but it's usually something like:

clang -E [your -I flags] myfile.cpp > myfile_pp.cpp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  clang