C++ GCC:调用静态对象的重写函数时发生异常
我使用的是GCC 3.4.3。该设备是基于ARM9/ARM11的POS终端PAX S80。下一个测试代码可以编译,但是在运行时调用重写的函数时,我得到一个异常C++ GCC:调用静态对象的重写函数时发生异常,c++,gcc,heap,virtual,C++,Gcc,Heap,Virtual,我使用的是GCC 3.4.3。该设备是基于ARM9/ARM11的POS终端PAX S80。下一个测试代码可以编译,但是在运行时调用重写的函数时,我得到一个异常 class TBase { public: int a; virtual void Foo() {a = 1;} void Exec() {Foo();} }; class TDerived : public TBase { public: virtual void Foo() {a
class TBase {
public:
int a;
virtual void Foo() {a = 1;}
void Exec() {Foo();}
};
class TDerived : public TBase {
public:
virtual void Foo() {a = 2;}
};
TBase *Base; //pointer to object in heap
TBase Base2; //static object
TDerived *Derived; //pointer to object in heap
TDerived Derived2; //static object
int main() {
Base = new TBase;
Base->Exec(); //this passes okay
Base2.Exec(); //this passes okay
Derived = new TDerived;
Derived->Exec(); //this passes okay
Derived2.Exec(); //here I get an exception and the app crashes
return 0;
}
这意味着我不能使用静态对象(Derived2)。是的,我可以在代码中创建对象(派生的),但这会使代码复杂化,因为我需要使用“new”操作符实例化对象
有什么技巧可以避免这个问题吗
顺便说一句,我在ARM926的Keil编译器上没有这个问题。不幸的是,我不能为这个设备选择编译器,只有GCC 3.4.3
谢谢你的建议 原因是没有初始化静态对象。所以,我决定手动操作 首先,我将下面几行添加到链接器脚本(): 其次,我调用一个函数,该函数调用静态对象()的所有构造函数:
void do\u ctor\u calls(){
typedef void(*调用(void));
外部调用\u ctor\u t\u ctors\u start\uuuuuu[];
外部调用u ctor_ut u ctors_uend_uu[];
call_ctor_t*ctor_call=\uuuuu ctors\u start\uuuuu;
而((无符号整数)*无符号整数调用!=0xFFFFFFFF)&((无符号整数)*无符号整数调用!=0x00000000)){
(*ctor_call)();
ctor_call++;
}
}
int main(){
do_ctor_calls();
/*我的代码在这里*/
返回0;
}
最终,重写的函数工作,静态对象照常运行。
谢谢大家 您会遇到什么异常?顺便问一下,您确定应用程序堆栈中的
//静态对象吗?我并不声称对“PAX S80”有任何了解,但通常全局变量在堆上的分配方式与通过new
相同。是的,你是对的。我已经更新了我的问题。异常消息如下:“警告!应用程序异常DFSR:000000 FD IFSR:00000000 2821e954 800000010,80000197”这在i386-64上运行得非常好,并且此功能非常基本,任何拱门上都不应该有任何差异。我怀疑这可能是一个编译器错误-你应该搜索GCC的错误数据库,看看是否找到类似的东西。终端供应商对这个问题怎么说?@Matt,不幸的是,我没有直接询问PAX,因为我们公司与当地PAX经销商有协议。公司规则,你知道的。在没有直接供应商支持的终端上编码是非常不愉快的,尤其是当您发现bug@Matt我习惯于在没有调试器和任何支持的情况下进行开发。所以,这很有趣;-)
__ctors_start__ = .;
KEEP(SORT(*)(.ctors))
__ctors_end__ = .;
void do_ctor_calls() {
typedef void (*call_ctor_t)(void);
extern call_ctor_t __ctors_start__[];
extern call_ctor_t __ctors_end__[];
call_ctor_t * ctor_call = __ctors_start__;
while ((ctor_call < __ctors_end__)&&((unsigned int)*ctor_call!=0xFFFFFFFF)&&((unsigned int)*ctor_call!=0x00000000)) {
(*ctor_call)();
ctor_call++;
}
}
int main() {
do_ctor_calls();
/* My code here */
return 0;
}