AlexandreRouma / SDRPlusPlus

Cross-Platform SDR Software

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Address the use of polymorphism throughout the codebase.

Ahmad-Bamba opened this issue · comments

Hello. My use-case for this SDR++ is using it as the back-end for a larger radio project. As such I am extending it with a plugin I am writing for personal use.

Feature description

While I was working to get my new plugin to compile, I noticed that the base classes of a lot of polymorphic types throughout the codebase are missing and/or are not declared as virtual. The first place I noticed this was in dsp::generic_block and dsp::block as you can see here. In C++, destructors must be labeled as virtual to tell the compiler to call the destructor of the base class when a child class is deleted. Furthermore, it's undefined behavior to delete a polymorphic child class whose base class does not have a virtual destructor. Doing so does not call the destructors of the base classes to free their resources, leading to resource leaks (see here).

Another example is ModuleManager::Instance here. Even though all plugins have to inherit from this class to work, the lack of a virtual destructor means that the deleteInstance function pointers may not actually work properly. They want to take a ModuleManager::Instance* and delete it, but can't due to the lack of a virtual destructor. Currently, most plugins take a void* and cast instead, which should be unnecessary.

There's a comment on dsp::buffer::Reshaper here that notes of problems with destructors not being called when expected, I believe most likely due to the lack of use of virtual on destructors throughout the codebase.

There is also some polymorphic hiding that could be addressed. dsp::block has a virutal init function that takes no parameters here. The init functions of the child classes usually have different, incompatible signatures. This means the compiler hides the base class init function instead of overriding. This causes no issues currently. But it does mean that if you create a container of dsp::block*s, and you want to ->init() all of them, that call won't actually initialize anything on most of the base class types.

clang-tidy's cppcoreguidelines-virtual-class-destructor check can be used to automatically catch most of these. Since I'm working off a fork, I've added workarounds for my own use. But I thought these observations, if addressed, may be helpful for others.

Seems that I forgot it for those two specific classes and it never really caused much issue. But yes I know it's required, all the other polymorphic classes have it.

There's a comment on dsp::buffer::Reshaper here that notes of problems with destructors not being called when expected, I believe most likely due to the lack of use of virtual on destructors throughout the codebase.

I think that's a comment left over from the previous version of the DSP library that was never removed, I'll check it out and see if it can be removed now.

This should be all of them fixed.

That's awesome, thanks a bunch!