Reputation: 2536
I've got a code really similar to the snippet below:
#include <vector>
struct dummy
{
std::vector<int> const data;
dummy() = default;
};
Most compilers accept this code without a glitch except clang
for versions 9 to 14 that says:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
note: default constructor of 'dummy' is implicitly deleted because field 'data' of const-qualified type 'const std::vector' would not be initialized
In clang 15
the issue disappears again.
Live
NB if const
is removed, the error disappears also.
Yet I would have expect data
to be initialized to a const
empty vector.
Is this a clang
bug? Otherwise, why is this code rejected (and why other compilers do not complain)?
Upvotes: 3
Views: 1243
Reputation: 76688
Before resolution of CWG 2394 a defaulted default constructor was defined as deleted, if any const
non-static member of class type without a default initializer did not have a user-provided default constructor.
The intention of this rule is to avoid the situation that you default-initialize the object to an indeterminate state that then can't possibly be modified to any usable state, which can only be wrong.
However, the condition isn't quite achieving that and the DR resolves it by making the same requirement as of const
variable declarations instead, which, after resolution of NB comment RU1 in P0490, correctly consider that even a non-user-provided default constructor may correctly initialize.
Now the issue is that libstdc++ implements the default constructor of std::vector
by defaulting it (see e.g. github mirror). The result is that the default constructor is not user-provided.
This seems to be a valid implementation, even before the CWG issue or NB comment resolution, because the container requirements are stated only in expressions and declarations that need to be well-formed and it doesn't seem to include any const
default initialization as far as I can tell.
So it will fail in Clang versions which don't yet implement the defect report and when using libstdc++.
I haven't checked, but the older versions of Clang are probably using older libstdc++ versions where the default constructor is not yet implemented this way. (see GCC commit e6cad9872b098f50aefb39019b6b1ba74d8c6c07 from 2018)
Upvotes: 6