omikron
omikron

Reputation: 2825

Weird uninitialized const member behavior

Consider this code snippet:

struct Foo {

};

template<typename T>
struct Bar {
    const T foo;
};

int main() {
    Bar<Foo> test;
}

I'm compiling it with g++-4.9.2 with [-std=c++11 -O0 -g3 -pedantic -Wall -Wextra -Wconversion] and getting error: uninitialized const member in ‘struct Bar<Foo>’. This is pretty obvious.

BUT try just add std::string as Foo member and program compiles!

#include <string>
struct Foo {
    std::string test;
};
// (...)

What happening? Replacing test's type into double causes program to fail to compile again. What string member changes in class?

Link to online compiler with this snippet.

It seems that gcc behaves like that since version 4.6.

Upvotes: 17

Views: 4481

Answers (3)

Jens
Jens

Reputation: 9406

I think it should consistently always produce an error. Clang does so. The C++ standard says in clause (4.3) of §12.1.4 that the default constructor is implicitly deleted when

— any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or equal-initializer does not have a user-provided default constructor,

As Foo does not have a user-provided default constructor, Bar should have an implicitly deleted default constructor and thus instantiating Bar<Foo> test in main should produce an error.

Maybe report a bug to GCC?

Upvotes: 18

Serge Ballesta
Serge Ballesta

Reputation: 148910

It looks like g++ automatically generates a default constructor even when const members should have been initialized at construction time because it knows that a string has a default constructor initializing it to an empty string. In fact all happens as if the source was :

struct Foo {
    std::string test;
    Foo():test() {;}
};

template<typename T>
struct Bar {
    const T foo;
    Bar(): foo() {;}
};

int main() {
    Bar<Foo> test;
}

which compiles fine both with clang and MSVC.

(but I must admit I still haven't found the reference in gcc doc explaining that ...)

Upvotes: 2

ravi
ravi

Reputation: 10733

If you have const data member in your class/struct, then compiler won't generate default constructor for that. You have to explicitly define it and initialize that const member ( not assign it ).

It should be an error in both cases.

Upvotes: 4

Related Questions