From C++11 Standard § 8.5 p6 we have:
If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.
The following code should not compile. But it does, both in Coliru and Ideone.
class A{};
int main() {
const A a;
}
Edit:
While trying to understand what's going on here, I ended up with the following code, which compiles (at least it's compliant with the Standard, as A
has a user-provided constructor). But then the following question came to my mind: which Standard clause does guarantee that a.b.j
is initialized with 0 (see the code in Ideone), below?
#include <iostream>
struct B { int j; B(){ std::cout << "B()" << '\n'; } };
struct A
{
struct B b;
int i;
public:
A(): i(1) { std::cout << "A()" << '\n'; }
};
int main() {
const A a;
std::cout << a.b.j << '\n';
std::cout << a.i << '\n';
}
Edit1:
Sorry for the Edit above, but I'm still not used with Unixes. Last week Dietmar Kühl called my attention to the fact that "Most UNIXes start off with zero initialized pages". Therefore, a.b.j is not 0 because of initialization, as I was thinking. As a matter of fact, I've just compiled the code with VS2010, and the result for a.b.j was an unitialized value, as expected. So, the question in Edit should be disregarded.
But I'm curious to know whether clang++ or g++ would also show an error for this second snippet. Thanks.
Having studied the rules for initialisation and aggregates, I conclude that you're right — this is technically ill-formed.
Your compiler is taking a shortcut because there are no members and thus no initialisation is practically required. (Funnily enough, the ancient GCC 4.1.2 rejects the program.)
Unfortunately I have nothing to quote because there is simply no rule overriding [C++11: 8.5/6]
for this case.
As for why the standard doesn't allow this, well why should it? Empty classes are of next to no use, I can't see a reason to bother with actively writing an exemption to the wider, more useful rule for this edge case.
Taking into account a note in paragraph #2 of section 7.1.6.1 The cv-qualifiers where there is written:
2 [ Note: Declaring a variable const can affect its linkage (7.1.1) and its usability in constant expressions (5.19). As described in 8.5, the definition of an object or subobject of const-qualified type must specify an initializer or be subject to default-initialization. —end note ]
it seems that indeed the compilers bahave oddly.
Though if you will add a data member the code will not be compiled in ideone but will be compiled at least in MS VC++ 2010. In the quote you presented there is nothing said about data members.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With