使用链接时间代码生成时VC ++ 2010是否已损坏?

时间:2013-06-05 13:24:04

标签: c++ visual-studio-2010

我有一个带有一些虚函数的基类:

class cs
{
   <snip>
   virtual  void    Deactivate()    =   0;
   virtual  void    Update()    =   0;
   virtual  void    Render()    =   0;
   <snip>
};
然后我从这个基类派生一个类,它有Update()和Render函数。我称之为:

if (s_pActiveScene)
{
   s_pActiveScene->Update();
}

注意:s_pActiveScene是指向派生类的指针。

当我在iOS,Android,Mac上运行C代码时,一切正常。它也适用于Windows的调试模式(无优化)。但是,该调用(s_pActiveScene-&gt; Update();)在Windows发行版上崩溃(仅限整个程序优化=使用链接时间代码生成)。

这是编译器的缺陷,还是我做错了什么?

编辑:从新项目获得相同的行为,使用最少的代码如下:

---- main.cpp

#include "cs.h"
#include "csMain.h"
int main(int argc, char* argv[])
{
    Main.ActivateThisScene();
    cs::DoUpdate();
    return 0;
}

---- cs.h

#pragma once
class cs
{
public:
    void    ActivateThisScene();
    static  void    DoUpdate();
    virtual void    Update()        =   0;
protected:
    static  cs*     s_pActiveScene;
};

---- cs.cpp

#include "cs.h"
cs* cs::s_pActiveScene = 0;
void cs::ActivateThisScene()
{
    s_pActiveScene = this;
}
void cs::DoUpdate()
{
    if (s_pActiveScene)
    {
        s_pActiveScene->Update();
    }
}

---- csMain.h

#pragma once
#include "cs.h"
extern  class   csMain  Main;
class csMain : public cs  
{
public:
    void    Activate();
    void    Update();
};

---- csMain.cpp

#include "csMain.h"
class   csMain  Main;
void
csMain::Activate()
{
    ActivateThisScene();
}
void
csMain::Update()
{
    return;
}

2 个答案:

答案 0 :(得分:2)

是的,有问题。它与静态变量初始化顺序有关,或者确实是代码生成器错误。

这是机器代码

    Main.ActivateThisScene();

01361000  mov         eax,dword ptr [Main (1363064h)]  
01361005  mov         edx,dword ptr [eax]  ; this is supposed to be the 1st entry of VMT, but it is 0
01361007  mov         ecx,offset Main (1363064h)  
0136100C  mov         dword ptr [cs::s_pActiveScene (13633BCh)],ecx  

    cs::DoUpdate();
01361012  call        edx  ; access violation

您是否尝试将您的代码发布到social.msdn.microsoft.com上的VC论坛?

答案 1 :(得分:1)

它混合了多态性和静态,你可以像这样解决它:

//in csMain.cpp delete this static object
csMain  Main;

//in main.cpp create it dynamically
csMain *p = new csMain;
p->ActivateThisScene();
cs::DoUpdate();
delete p;