Reputation: 2825
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
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
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
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