https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77524

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Dave Rigby from comment #3)
> As an aside, std::queue<> (defaulting to using std::deque as the underlying
> Container) suffers from a similar issue - I see 4 allocations for an empty
> std::queue<int>. Is this the same underlying issue, or should I raise an
> additional bug on that?

Ouch. It's caused by the same issue, but the default constructor for std::queue
constructs a temporary of the underlying sequence, then move constructs the
data member from the temporary. With std::deque that means we allocate for the
temporary, then allocate again for the data member, then deallocate the memory
of the temporary. That sucks.

      explicit
      queue(_Sequence&& __c = _Sequence())
      : c(std::move(__c)) { }

IIRC the "default" constructor is defined that way so that it's possible to
explicitly instantiate std::queue<_Sequence> with a non-DefaultConstructible
_Sequence. But it means std::queue<std:deque<T>> is horribly inefficient. At
least for an empty std::deque<T> the initial allocation is probably going to
end up being useful, because in most cases the deque doesn't stay empty and the
allocation ends up being useful later. In this std::queue constructor the
temporary is definitely never used (it goes out of scope immediately) so
pre-allocating is entirely useless. std::stack has the same issue.

Please create a new bug for those container adaptors, as that can and should be
fixed for the default configuration. We'll keep this bug for the
non-backwards-compatible std::deque change to be done at some future date.
Thanks.

Reply via email to