c++ - 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 中工作得很好。
解决方案
您的代码具有未定义的行为。的基类类型B
isA<int, BlaEnum::Bla2>
但您声明Base
为 aA<int>*
扩展为 a A<int, BlaEnum::Bla1>*
。A<int, BlaEnum::Bla2>*
将 a 强制转换为 aA<int, BlaEnum::Bla1>*
并通过它访问是一种严格的别名违规。
推荐阅读
- python-3.x - 在 Pandas DF 匹配文本中突出显示文本(字符串类型)
- keycloak - 无法在 keycloak 中创建初始管理员用户
- python - 列表中字典中的重复键
- node.js - 如何在服务器上运行 NodeJs SocketIO(Centos 7)
- amazon-web-services - 我需要存储来自cli的多个aws glacier启动作业请求的jobid
- python - 如何在子进程运行时从子进程中获取标准输出?
- shell - 带表的 foreach 命令
- rest - 领英 V2 API
- java - JAVA 中的 FIX 协议示例源代码?
- fix-protocol - FIX 协议:未按要求顺序指定的标签