Bug 56437

Summary: basic_string assumes that allocators are default-constructible
Product: gcc Reporter: Thomas Neumann <tneumann>
Component: libstdc++Assignee: Jonathan Wakely <redi>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P3    
Version: 4.8.0   
Target Milestone: 5.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2014-09-19 00:00:00
Bug Depends on:    
Bug Blocks: 24882    
Attachments: example

Description Thomas Neumann 2013-02-24 23:39:56 UTC
Created attachment 29531 [details]
example

The empty-string optimization of basic_string assumes that allocators are default constructible. While this used to be the case in C++98, it is no longer true in C++11, as now allocators are allowed to have state.

Consider the attached example program. Compiling with

g++ -std=c++11 -c t.cpp

produces an error message, even though it should compile fine. The problem is the the "_S_construct" calls "_Alloc()", which does not exist.

Note that the C++11 standard does not require default constructors. (Section 17.6.3.5, Table 28). In particular, the SimpleAllocator example from Section 17.6.3.5 would trigger the same bug, too.
Comment 1 Jonathan Wakely 2013-02-25 00:08:35 UTC
This is hardly the only C++11 allocator requirement missing from std::string, ALL of the new requirements are missing, and unlikely to be implemented until we switch to a non-COW string implementation.
Comment 2 Jonathan Wakely 2013-02-25 00:11:16 UTC
C++11 allocators are not required to define any of these:

   typedef T* pointer;
   typedef const T* const_pointer;
   typedef T& reference;
   typedef const T& const_reference;
   typedef unsigned size_type;
   typedef int difference_type;
   template <class U> struct rebind { typedef MyAllocator<U> other; };

But if your allocator fails to define any of them then std::string (and some of the other containers) will fail to compile. This is a known issue.
Comment 3 Thomas Neumann 2013-02-25 06:31:43 UTC
(In reply to comment #1)
> This is hardly the only C++11 allocator requirement missing from std::string,
> ALL of the new requirements are missing, and unlikely to be implemented until
> we switch to a non-COW string implementation.

Well, but this would be an allocator requirement that is easy to fix. There are only three places with "_Alloc()" in basic_string.tcc, and only two would have to be fixed as far as I can see it.

I am not sure yet why the code even tries to construct the allocator, but if necessary we could use is_default_constructible to figure out of the constructor is available. I could try to produce a patch myself if you prefer. But as of new basic_string is quite unusable with stateful allocators.
Comment 4 Paolo Carlini 2013-02-25 11:17:30 UTC
Note that all such changes should be applied to ext/vstring (which will become basic_string in 4.9) not to basic_string. By now the latter is frozen, modulo serious regressions.
Comment 5 Jonathan Wakely 2014-12-22 13:50:54 UTC
Fixed for GCC 5 (when using the new string ABI)