Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The snippet shown below compiles in Coliru and Ideone, but according to iso § 8.5 p6 it shouldn't, or am I missing something?

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.

like image 552
Wake up Brazil Avatar asked Jan 03 '14 17:01

Wake up Brazil


2 Answers

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.

like image 91
Lightness Races in Orbit Avatar answered Oct 21 '22 00:10

Lightness Races in Orbit


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.

like image 26
Vlad from Moscow Avatar answered Oct 21 '22 00:10

Vlad from Moscow