一年多来,我一直在使用 C++ 为 Microblaze 处理器开发嵌入式软件。我的设计并没有那么复杂,所以我没有使用该语言强大的、面向对象的特性。
有一段时间,我一直在尝试增强我的设计结构。为此,我尝试广泛使用 C++ 的复杂特性,例如继承、多态等。作为新手,我相信单独使用继承不会影响代码大小。只有多态性有一些副作用,例如添加虚拟表指针、运行时类型信息等。我的问题始于向基类添加纯虚拟成员函数。
为了提供一个可运行的示例,我将尝试模仿我所面临的情况。
下面的代码编译并生成13292 字节的代码。这段代码不可能有这么多的指令。但是,我相信生成的 BSP 中的某些部分是在生成 elf 文件时必须包含的。
class Base{
public:
Base() = default;
~Base() = default;
virtual void func() {}
int m_int;
};
class Derived : public Base{
public:
Derived() = default;
~Derived() = default;
void func() final {}
int m_int2;
};
int main()
{
Derived d;
while(1);
}
当您认为您有近 128KB 的可用 RAM 时,13KB并不算多。实际上,直到出现纯虚函数的问题时,我才注意到生成的代码的大小。下面的第二个代码具有相同的结构,只是func()
现在是一个纯虚函数。构建此代码为我们提供了一个大于可用*(128KB)* RAM 大小的代码大小。因此,我修改了链接器文件以添加一些假 RAM,以便能够编译代码。编译成功后,生成的代码大小接近157KB!
class Base{
public:
Base() = default;
~Base() = default;
virtual void func() = 0;
int m_int;
};
class Derived : public Base{
public:
Derived() = default;
~Derived() = default;
void func() final {}
int m_int2;
};
int main()
{
Derived d;
while(1);
}
我没有更改编译器的任何首选项,所有参数都处于默认状态。除了自动生成的库之外,没有其他库。你认为问题可能是什么?
一些附加说明
- 我在两个不同的 IDE 上尝试了代码。Vivado SDK 2017.2 和 Vitis 2019.2
- 同样的问题也适用于动态分配调用(操作员 new 和 delete)。用 C 风格的 malloc 和 free 替换它们可以解决问题。
- 以发布模式构建代码也解决了这个问题。在发布模式下,无论我是否使用纯虚函数,生成的代码都是 1900 字节。
如果需要,我可以提供更多信息,谢谢
我在赛灵思论坛上问过同样的问题,你可以在 这里找到