Main Content

Empty destructors may cause unnecessary data copies

User-declared empty destructors prevent autogeneration of move constructors and move assignment operators

Since R2020a

Description

This defect occurs when a class definition contains a user-defined destructor that has an empty or =default implementation and does not declare both a move constructor and move assignment operator. For instance:

class aClass
{
public:
    ~aClass() noexcept
     {} // Empty body
};
class bClass
{
public:
    ~bClass() = default;
};
The destructors above are exactly the same as the compiler provided version, but they prevent automatic generation of the move operators. As a result, the class type is not movable.

An empty destructor is not flagged if:

  • The destructor is private or protected.

  • The destructor is declared final.

  • The destructor is declared virtual and does not override a base class destructor.

  • The destructor overrides a base class pure virtual destructor.

  • The class has a trivial copy constructor (and therefore a copy operation is not more expensive than a move operation).

Risk

Instances of this class might be unnecessarily copied in situations where a move operation would have been possible. Copy operations are more expensive than move operations and might impact performance.

Fix

Try one of these solutions:

  • Remove the empty destructor if possible. If a class does not have a destructor, the compiler generates a destructor, which is essentially the empty destructor that you explicitly declared.

    See also Rule of Zero.

  • If you cannot remove the destructor, add an explicit move constructor and move assignment operator to the class definition. Use the =default syntax to clarify that the compiler definitions of move constructors and move assignment operators are used.

    class aClass
    {
    public:
         ~aClass() noexcept = default;
         aClass(aClass&& ) = default;
         aClass& operator=(aClass&& ) = default;
    };

    See also Rule of Five.

Performance improvements might vary based on the compiler, library implementation, and environment that you are using.

Result Information

Group: Performance
Language: C++
Default: Off
Command-Line Syntax: EMPTY_DESTRUCTOR_DEFINED
Impact: Low

Version History

Introduced in R2020a