免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2882 | 回复: 3
打印 上一主题 下一主题

[C++] GCC对类成员指针的奇怪处理,请教原因 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-11 10:17 |只看该作者 |倒序浏览
  1. #include <iostream>

  2. using namespace std;

  3. class p3d {
  4. public:
  5.   p3d():x(9), y(18), z(27) { }
  6.   virtual void func();
  7.   virtual ~p3d();
  8.   static p3d origin;
  9.   int x; int y; int z;
  10. };

  11. void
  12. p3d::func() { }

  13. p3d::~p3d() { }

  14. int
  15. main() {
  16.   p3d inst;
  17.   int p3d::*p1 = &p3d::z;
  18.   inst.*p1 = 65535;
  19.   cout<<p1;
  20.   return 0;
  21. }
复制代码

运行结果,按我的理解应该是12,考虑虚函数表指针放在对象开头的情况,这个值应该是16。

《Inside the C++ Object Model》里面说是13,17,加1是为了处理类似

  1.   int p3d::*p1 = &p3d::z;
  2.   int p3d::*p2 = 0;
  3.   if (p1 == p2) ...
复制代码
这样的代码。

但是gcc 3.2.3上的实际运行的结果是——1。

g++ -S 编译得到的汇编代码是
  1.         movl    $12, -28(%ebp)
  2.         leal    -24(%ebp), %eax
  3.         addl    -28(%ebp), %eax
  4.         movl    $65535, (%eax)
  5.         subl    $8, %esp
  6.         cmpl    $-1, -28(%ebp)
  7.         setne   %al
  8.         movzbl  %al, %eax
  9.         pushl   %eax
  10.         pushl   $_ZSt4cout
  11.         call    _ZNSolsEb
复制代码

-24(%ebp)应该是inst的地址,-28(%ebp)是成员z的偏移量,而这个偏移量如第一行所示,确实是12。
movl    $65535, (%eax)对应的就是赋值,把常数写到inst的成员z的地址里面去。
后面的处理我就看不懂了,按我的理解应该是
  1.         movl    $12, -28(%ebp)
  2.         leal    -24(%ebp), %eax
  3.         addl    -28(%ebp), %eax
  4.         movl    $65535, (%eax)
  5.         subl    $8, %esp    #这句话的作用我不懂
  6.         leal -28(%ebp), %eax    #直接把z在p3d里的偏移量装载到eax当参数就可以了亚
  7.         pushl   %eax
  8.         pushl   $_ZSt4cout
  9.         call    _ZNSolsEb
复制代码

求GCC高手帮忙解惑,谢谢!

论坛徽章:
0
2 [报告]
发表于 2008-06-12 10:09 |只看该作者

不是吧!!

五十多个查看都没有一个回复的?
我把它翻出来继续求解~

论坛徽章:
0
3 [报告]
发表于 2014-03-30 19:00 |只看该作者
不能使用cout打印出来偏移量而应该使用printf
    printf("%p\n", p1);
    printf("%p\n", p2);
    printf("%p\n", p3);
这样的输出结果为:
0x8
0xc
0x10
如果使用%d,打出来的结果也是 8 12,16


----------------------------
机器为64位,前8个字节应该为vptr

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
4 [报告]
发表于 2014-03-31 08:23 |只看该作者
输出1,是因为cout将之隐式转化为bool
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP