5

By analyzing code using SonarLint, I got a message (the title of the question) about a destructor that is declared like below:

class Foo
{
public:
.   // default ctor
.   // parameterized ctor
.
    inline ~Foo() = default; // dtor
.
.   // copy ctor = delete
.   // copy assignment operator = delete
.   // move ctor
.   // move assignment operator

private:
    ...
    mutable std::vector< std::vector<char> > m_Matrix;
    ...
};

Here is the message's description: Declaring a function or a static member variable constexpr makes it implicitly inline.

I don't think the dtor of this class can be constexpr or consteval because it has a non-static data member of type std::vector so ~Foo has to call delete[] at some point to deallocate the vector's storage.

So why is SonarLint showing this message? Is it because of = default? Does any defaulted special member function become implicitly constexpr?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
digito_evo
  • 3,216
  • 2
  • 14
  • 42
  • 6
    Even ignoring constexpr, every member function defined in class body is implicitly inline. – HolyBlackCat Jan 07 '22 at 13:10
  • 1
    Manually defining an empty/default destructor is almost always a mistake, unless you also define the copy/move operations. It silently replaces copying your class with moving, e.g.: https://gcc.godbolt.org/z/GTzdE9azs – HolyBlackCat Jan 07 '22 at 13:12
  • @HolyBlackCat So even making it ` = default` will mean that it's implicitly inline? – digito_evo Jan 07 '22 at 13:14
  • @HolyBlackCat My class has a move ctor and a move assignment operator and also I have deleted both copy ctor and copy assignment operator. Is this setup ok? – digito_evo Jan 07 '22 at 13:16
  • Yes, it's ok in that case. But you can remove it completely, and nothing will change. – HolyBlackCat Jan 07 '22 at 13:18
  • @HolyBlackCat Oh ok. But what exactly do you mean by "remove it completely"? Should I remove the declarations and definitions of move ctor and move operator and also remove the deleted declarations of copy ctor and copy operator? And also remove the declaration of the defaulted dtor? Is this the ***rule of zero***? What about the def ctor and parameterized ctor? I don't think I should remove them. – digito_evo Jan 07 '22 at 13:21
  • 2
    @digito_evo "remove it" likely meant "remove the destructor (defaulted) definition". – Daniel Langr Jan 07 '22 at 13:27
  • 1
    @digito_evo When you define a function inside a class definition, it is implicitly defined as inline. `~Foo() = default;` is considered a definition, so it will be inlined automagically. – NathanOliver Jan 07 '22 at 13:36
  • 2
    Yes, sorry, I meant remove the defaulted destructor. But regarding the move operations, if they only move `m_Matrix`, then they should be `=default`ed, and deleted copy operations can optionally be removed, because they're deleted automatically when you have custom (or defaulted) move operations. Or, if you don't mind the class being copyable, you can remove remove both copy and move operations. – HolyBlackCat Jan 07 '22 at 13:37
  • @HolyBlackCat I was looking for that. Thanks for the info. – digito_evo Jan 07 '22 at 14:59
  • @NathanOliver I understand. Thanks for your help. – digito_evo Jan 07 '22 at 15:02
  • 1
    The only use case for a defaulted destructor I have seen is `virtual ~Foo() = default;`. when you *need* to have a virtual destructor in a base class, but it has nothing to do. – BoP Jan 07 '22 at 15:25

1 Answers1

5

Yes:

An explicitly-defaulted function that is not defined as deleted may be declared constexpr or consteval only if it is constexpr-compatible ([special], [class.compare.default]). A function explicitly defaulted on its first declaration is implicitly inline ([dcl.inline]), and is implicitly constexpr ([dcl.constexpr]) if it is constexpr-compatible.

(From Explicitly defaulted functions, emphasis mine.)

Foo is likely constexpr-compatible in C++20, because std::vector can now be constexpr.

sigma
  • 2,758
  • 1
  • 14
  • 18