Consider the code: #include <map> class a { public: a(); }; class b { public: // implicit default ctor bool operator<(const b& rhs) const; private: a a_val; }; typedef std::map<b, int> my_map; void func() { my_map::value_type x; } That compiled correctly with 4.3.2. It fails to compile with pre-4.4 trunk: Using built-in specs. Target: i686-linux Configured with: ../trunk/configure --enable-languages=c,c++ --build=i686-linux --host=i686-linux --target=i686-linux --prefix=/g/users/cgd/proj/gcc-trunk/bld/../inst Thread model: posix gcc version 4.4.0 20081123 (experimental) (GCC) with the error: In file included from [...]/bin/../lib/gcc/i686-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_algobase.h:71, from [...]/bin/../lib/gcc/i686-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_tree.h:67, from [...]/bin/../lib/gcc/i686-linux/4.4.0/../../../../include/c++/4.4.0/map:65, from test2.cc:1: [...]/bin/../lib/gcc/i686-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_pair.h: In constructor 'std::pair<_T1, _T2>::pair() [with _T1 = const b, _T2 = int]': test2.cc:20: instantiated from here [...]/bin/../lib/gcc/i686-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_pair.h:84: error: uninitialized member 'std::pair<const b, int>::first' with 'const' type 'const b' Looking at the preprocessed source (which i'll attach shortly), I see that pair's default ctor is: pair() : first(), second() { } I don't know if that's "right," but the C++98 std says that: "Initializes its members as if implemented: pair() : first(T1()), second(T2()) {}" (20.2.2, paragraph 2.) If I change the pair() ctor to be: pair() : first(_T1()), second(_T2()) { } (by hacking the preprocessed source), the result compiles correctly. (I'm *so* far from an expert on STL that I'm not 100% sure that sample code is actually valid, but on its face it seems reasonable at least, and 4.3.x accepted it, and Comeau's test drive accepts it as well.)
Created attachment 16750 [details] preprocessed source from test case in bug report.
There is a defect report which changed C++98 dealing with default initialization which might be causing this issue, see DR178.
The default constructor of pair just implements DR 265, this is *very* old: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#265 This is possibly a C++ front-end issue, because lately nothing changed in the library in this area. I'll CC Jason.
The below is a pure C++ testcase, which EDG accepts and mainline rejects. Jason can you look a bit into it? Thanks in advance! //////////////// template<class _T1, class _T2> struct pair { _T1 first; _T2 second; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 265. std::pair::pair() effects overly restrictive /** The default constructor creates @c first and @c second using their * respective default constructors. */ pair() : first(), second() { } }; class a { public: a(); }; class b { public: // implicit default ctor bool operator<(const b& rhs) const; private: a a_val; }; typedef pair<const b, int> my_pair; void func() { my_pair x; }
Subject: Bug 38233 Author: jason Date: Fri Nov 28 23:35:37 2008 New Revision: 142265 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142265 Log: PR c++/38233 * init.c (perform_member_init): Fix value-initialization. (build_value_init_1): Add assert to catch cases that will break in the gimplifier. (build_default_init): Remove. * cp-tree.h: Remove its prototype. * pt.c (tsubst_expr) [DECL_EXPR]: Use build_value_init for value-initialization. Added: trunk/gcc/testsuite/g++.dg/init/array25.C trunk/gcc/testsuite/g++.dg/init/value4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/init.c trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Fixed.