https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80284
Bug ID: 80284
Summary: Support of associative containers with incomplete
element type
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: frankhb1989 at gmail dot com
Target Milestone: ---
https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z
shows that "the feature" of N4510 (except the feature-test macro) has been
supported long ago from 3.0. It is not very clear whether "the feature" is
applicable on other containers not currently required by the proposed (and
accepted by the working draft) rules of N4510 yet.
I don't find the answer in the documentation, but I still tend to guess other
containers can work in libstdc++, for several reasons:
1. N4510 mentions associative/unordered containers as well. It just not ready
to require it for all implementations.
2. N4510 mentions boost.containers in parallel, which clearly states the
support of incomplete element types for other containers in its documentation.
3. They (from libstdc++) can actually work as expected (at least for naive
cases).
The real problem raises when I meet some not-so-naive cases. Test case:
#include <map>
#include <string>
using namespace std;
struct node
{
using container_t = map<string, node>;
string name;
container_t container;
node(const string& n)
: container(), name(n)
{}
node(container_t&& con, const string& s)
: container(move(con)), name(s)
{}
void
swap(node& nd) noexcept
{
name.swap(nd.name);
container.swap(nd.container);
}
};
int main()
{
node n(node::container_t{{"a", node("a")}}, "A");
n.swap(n.container.begin()->second);
}
Despite the undefined behavior caused by incomplete template argument as per
the standard, it seems well-formed. However, it leaks. I've reproduced it on
GCC 5.3 + DrMemory on Windows/GCC 6.3.1 + valgrind on Linux. It can also
reproduced with clang++ instead of g++.
Is it intended by design?