I learnt about the explicit keyword in c++ and its uses. Then for practice I wrote the following program that works with MSVC but not with gcc and clang. Demo.
class Testing
{
public:
explicit Testing() = default;
};
int main()
{
Testing t[2] = {}; //works with msvc but not with gcc and clang
}
As you can see, the above works with msvc but not with clang and gcc. I am using C++20 and want to know which compiler is correct for this example according to the C++20 standard.
GCC produces the following error:
<source>:8:21: error: converting to 'Testing' from initializer list would use explicit constructor 'constexpr Testing::Testing()'
8 | Testing t[2] = {}; //works with msvc but not with gcc and clang
| ^
The program is ill-formed and gcc and clang are correct in rejecting the program because
Testing t[2]={};is copy-list-initialization and sincetis an array it uses aggregate initialization which in turn result in copy initialization oft's member(s) using the empty initializer list{}which fails as the default ctor is explicit(and soTesting::Testing()cannot be used in copy initialization).This is explained in detail below.
From list initialization:
This means that since
Tin our example isTesting[2]which is an array(and so an aggregate), aggregate initialization will be performed.Next, from aggregate initialization:
This means that the array elements(which are not explicitly initialized btw) will be copy initialized from an empty initializer list
{}. What this in turn means is that it is as if for each element of the array we're writingTesting array_element_nth = {};which results in value-initialization as per dcl.init.list#3.5:Next, from value initialization:
This means that the array element will be default initialized.
So we move onto default initialization:
This means that that the constructors will be enumerated and best of them will be chosen with
(). So we move onto over.match.ctor:This means that the default ctor will be used but since this is in copy initialization context, the explicit ctor cannot be used.
Thus, msvc is wrong in accepting the program.
Here is the msvc bug:
MSVC compiles invalid program involving explicit constructor