- 论坛徽章:
- 0
|
- #include <iostream>
- using namespace std;
- class p3d {
- public:
- p3d():x(9), y(18), z(27) { }
- virtual void func();
- virtual ~p3d();
- static p3d origin;
- int x; int y; int z;
- };
- void
- p3d::func() { }
- p3d::~p3d() { }
- int
- main() {
- p3d inst;
- int p3d::*p1 = &p3d::z;
- inst.*p1 = 65535;
- cout<<p1;
- return 0;
- }
复制代码
运行结果,按我的理解应该是12,考虑虚函数表指针放在对象开头的情况,这个值应该是16。
《Inside the C++ Object Model》里面说是13,17,加1是为了处理类似
- int p3d::*p1 = &p3d::z;
- int p3d::*p2 = 0;
- if (p1 == p2) ...
复制代码 这样的代码。
但是gcc 3.2.3上的实际运行的结果是——1。
g++ -S 编译得到的汇编代码是
- movl $12, -28(%ebp)
- leal -24(%ebp), %eax
- addl -28(%ebp), %eax
- movl $65535, (%eax)
- subl $8, %esp
- cmpl $-1, -28(%ebp)
- setne %al
- movzbl %al, %eax
- pushl %eax
- pushl $_ZSt4cout
- call _ZNSolsEb
复制代码
-24(%ebp)应该是inst的地址,-28(%ebp)是成员z的偏移量,而这个偏移量如第一行所示,确实是12。
movl $65535, (%eax)对应的就是赋值,把常数写到inst的成员z的地址里面去。
后面的处理我就看不懂了,按我的理解应该是
- movl $12, -28(%ebp)
- leal -24(%ebp), %eax
- addl -28(%ebp), %eax
- movl $65535, (%eax)
- subl $8, %esp #这句话的作用我不懂
- leal -28(%ebp), %eax #直接把z在p3d里的偏移量装载到eax当参数就可以了亚
- pushl %eax
- pushl $_ZSt4cout
- call _ZNSolsEb
复制代码
求GCC高手帮忙解惑,谢谢! |
|