Comeau, g++ (ideone) and EDG accept the following code without diagnostic. Visual C++ compiles successfully, albeit with warning C4624.
class indestructible_bas
Well, if the automatically-generated constructor calls a possibly-throwing constructor, then it will give the same access error.
#include <string>
class indestructible_base
{
~indestructible_base();
std::string s; // <------ this may throw
};
class T : indestructible_base
{
public:
//T() {}
};
int main(void) { new T(); }
So I guess exceptions is the answer. In ANSI ISO IEC 14882 the only noexcept(true)
string constructor is the move constructor. I believe this should compile but ideone says no.
I suspect that this might be compiler-specific behavior. Here's my theory:
Because (in this particular case) an implicitly-defined T() is a trivial constructor (as defined in 12.1(5) of the standard), the compiler doesn't even attempt to generate a body for T(). Since there's no ctor body, there are no exceptions that could possibly be generated during "construction" (of which there isn't any, really), so there's no need to generate a dtor call, and so no need to generate a dtor body, only to find out that the base class's dtor is private.
But as soon as T() becomes non-trivial (even if it remains implicitly-defined), a ctor body must be generated, and you get the error. Something as simple as adding a member to class T that has a user-defined constructor would make the implicitly-defined T() become non-trivial.
A separate, but related, issue is that new T()
doesn't generate a dtor call (since you don't have a corresponding delete
anywhere). In contrast, if I just replace new T()
with T dummy
in your code, then I get the following from gcc
, suggesting that it's now doing the full check for dtor accessibility (as a consequence of having to generate a dtor call):
test.cpp: In destructor 'T::~T()':
test.cpp:3: error: 'indestructible_base::~indestructible_base()' is private
test.cpp:7: error: within this context
test.cpp: In function 'int main()':
test.cpp:12: note: synthesized method 'T::~T()' first required here
test.cpp:12: warning: unused variable 'dummy'