内联函数的问题,请高手来解答一下,

karlfly 2010-07-05 11:18:15
碰到一个从未见过的问题:
在类定义中实现函数,其中有一个返回值与实际不一致!此函数实现在CPP文件中却正常,我这个情况大概表示如下:

类A:
class A
{
A():a(100),b(200){}
...

protected:
...
int a;
int b;
}


类B:用内联函数返回成员的值
class B :public A
{
...
GetValueA() { return a; }
GetValueB() { return b; }
}


例如
现在new一个B对象,调用GetValueB()得到的值不是200,而是固定的另一内存单元的值,
写成GetValueB() { int ret = b; return ret; } 时还是一样,
但是如果将GetValueB()实现在CPP文件中,却是正常,得到的是200。

实在不知道为什么会这样,因为GetValueA(),GetValueC(),等其它的内联返回成员值却是正常的。通过调试发现是取成员b的值时位置计算错误(偏移差几字节)
汇编信息如下:
42: class CMyClientSession : public ClientSession
...
省略几行
...
61: UInt32 GetStartInSec() { return fStartPlayTimeInSec; }
62: UInt32 GetDurationInSec()
63: {
010754D0 push ebp
010754D1 mov ebp,esp
010754D3 sub esp,0C8h
010754D9 push ebx
010754DA push esi
010754DB push edi
010754DC push ecx
010754DD lea edi,[ebp-0C8h]
010754E3 mov ecx,32h
010754E8 mov eax,0CCCCCCCCh
010754ED rep stos dword ptr [edi]
010754EF pop ecx
010754F0 mov dword ptr [ebp-4],ecx
64:
65:
66: UInt32 fDur = fDurationInSec;
010754F3 mov eax,dword ptr [ebp-4]
010754F6 mov ecx,dword ptr [eax+0D6h]
010754FC mov dword ptr [ebp-8],ecx
67: return fDur; //fDurationInSec;
01075537 mov eax,dword ptr [ebp-8]
68: }

断点在67行时:
eax值为0x01f00068, 为对象首地址,没错。
fDurationInSec 地址为0x01f00150, 值为 0x000000e6, 没错。
ecx值为0x0118003e(一直得到的结果是这个值),因为它是eax+0D6h单元的值,而eax+0D6h为0x01f0013e, 没有定位到fDurationInSec的正确地址0x01f00150。偏差了18个字节。


为什么内联函数得到成员的值时会产生偏差? 我在GetDurationInSec()中加上取成员fStartPlayTimeInSec也是一样的会偏差18字节,而且只有我这个GetDurationInSec()函数会这样,其它函数正常。GetDurationInSec()函数实现体写在CPP文件中时却又正常。

期待高手解答。
...全文
143 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
hitrose27 2010-07-05
  • 打赏
  • 举报
回复
当把函数实现写在类内部时,便器默认的选项是inline;

但是inline需要在每一个声明或者实现该函数的地方都出现inline的关键字,

所以,还是加上inline吧,编译器的默认行为是不可捉摸的……

每一个都有区别……
xgPaul 2010-07-05
  • 打赏
  • 举报
回复
#include "iostream.h"
class A
{
public:
A():a(100),b(200){}
~A(){}

protected:

int a;
int b;
};

class B : public A
{
public:
B(){}
~B(){}

inline int GetValueA() { return a; }
inline int GetValueB() { return b; }
};


void main()
{
B* temp=new B();
int i=temp->GetValueB();
cout<<i<<endl;
delete temp;
}



我把上面代码试了一下,输出的是200。
雪影 2010-07-05
  • 打赏
  • 举报
回复
lz代码中的内联函数没什么问题啊
jameshooo 2010-07-05
  • 打赏
  • 举报
回复
在你的类B里面也有一个叫做b的成员变量吧

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧