首页 > 解决方案 > c++ 在派生中定义模板化基类在 IAR ARM 编译器中不起作用

问题描述

在为 ARM 设备构建时,此场景适用于 Visual Studio,但不适用于 IAR,我遇到了一个严重错误。这是场景

enum  BlaEnum
{
  Bla1,
  Bla2
};

template <class T, BlaEnum bla = Bla1>
class A
{
public:
   virtual void Foo() = 0;
   T att;
   BlaEnum bll;
};

class B : public A<int, BlaEnum::Bla2>
{
public:
   void Foo() override;
};

int youu = 9;
void B::Foo() {
++youu;
}

int main(void)
{

 B b;
 A<int>* Base = (A<int>*) &b;  
 Base1->Foo(); //works for win32 but hard faults when it runs in ARM device

 B b2;
 A<int,BlaEnum::Bla2>* Base2 =  &b2;  
 Base2->Foo(); //works for both ARM and win32

}

我在派生类中定义抽象基类模板。每个派生类都会以不同的方式定义枚举常量,我知道这会给 IAR 编译器如何实现动态多态性带来问题。
我注意到 vtable 无法在 ARM 设备中创建,因为 vptr 指向无法访问的位置。但是对于 win32,vtable 对这两种情况都很好。

问题是,为什么这会导致构建到 ARM 设备的问题,但在 win32 中工作得很好。

标签: c++templatesarmabstractiar

解决方案


您的代码具有未定义的行为。的基类类型BisA<int, BlaEnum::Bla2>但您声明Base为 aA<int>*扩展为 a A<int, BlaEnum::Bla1>*A<int, BlaEnum::Bla2>*将 a 强制转换为 aA<int, BlaEnum::Bla1>*并通过它访问是一种严格的别名违规。


推荐阅读