The following code compiles with Visual Studio 2019, but not with gcc and clang. Defining the variable b causes an error with the latter two compilers.
#include <iostream>
class base
{
public:
constexpr base(int i) : m_i(i) {}
constexpr int i() const { return m_i; }
protected:
~base() = default; // Forbid polymorphic deletion
private:
const int m_i;
};
class derived final : public base
{
public:
constexpr derived() : base(42) {}
};
// Defining b compiles with Visual Studio 2019,
// but does not with gcc and clang.
// gcc 11.2: error: 'base::~base()' is protected within this context
// clang 13.0: error: variable of type 'const base' has protected destructor
constexpr base b(41);
// Defining d compiles with all 3 compilers.
constexpr derived d;
int main()
{
std::cout << b.i() << std::endl;
std::cout << d.i() << std::endl;
}
Which of the compilers are right? Microsoft, which compiles the program, or gcc and clang, which do not?
And if gcc and clang are right, why does the error show up for b, but not for d?
Update:
FWIW, if I change base as below, Visual Studio 2019 does not compile the program either:
class base
{
public:
constexpr base(int i) : m_i(i) {}
constexpr int i() const { return m_i; }
protected:
//~base() = default; // Forbid polymorphic deletion
// This does not compile with Visual Studio 2019 either.
~base() {}
private:
const int m_i;
};
But as I understand, there shouldn't be a difference between the defaulted and the manually implemented destructor, so yes, a bug in the MS compiler it is then, I guess.