Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

On stateful allocators and GCC

42 views
Skip to first unread message

Daniel

unread,
Sep 9, 2019, 11:54:37 PM9/9/19
to
Has anyone attempted to use stateful allocators with GCC basic_string?

My attempts with versions up to 9 result in a compile time error

/usr/include/c++/9/bits/basic_string.tcc:596:30: error: no matching function for call to ‘my_alloc::my_alloc()’
596 | if (__n == 0 && __a == _Alloc())

My example allocator my_alloc doesn't have a default constructor, which I don't think you would ever want on a stateful allocator. So why would GCC
want to compare the passed allocator __a with the default constructed
allocator _Alloc()?

I have no issues with vs or clang.

Thanks,
Daniel



Melzzzzz

unread,
Sep 10, 2019, 12:00:58 AM9/10/19
to
Don't know about allocator requirements, but if default constructor is
not one of them it is a bug in gcc...
>
> I have no issues with vs or clang.
>
> Thanks,
> Daniel
>
>
>


--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala

Öö Tiib

unread,
Sep 10, 2019, 3:25:40 AM9/10/19
to
Bugzilla say it is RESOLVED FIXED for gcc 5 ages ago.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
Is it regression so someone had added the _Alloc() back,
or are you using very old gcc?

Öö Tiib

unread,
Sep 10, 2019, 4:04:36 AM9/10/19
to

Daniel

unread,
Sep 10, 2019, 7:52:06 AM9/10/19
to
On Tuesday, September 10, 2019 at 4:04:36 AM UTC-4, Öö Tiib wrote:
> >
> > Bugzilla say it is RESOLVED FIXED for gcc 5 ages ago.
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56437
> > Is it regression so someone had added the _Alloc() back,
> > or are you using very old gcc?
>

Sounds plausible, but I'm at a loss to understand how. The builds are being
done under travis, and the entries in .travis.yml look like, e.g.

- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
env: COMPILER=gcc VERSION=8 CXXFLAGS="-std=c++17

> Demo: http://coliru.stacked-crooked.com/a/823d838b73d969b4

But will double check.

James Kuyper

unread,
Sep 10, 2019, 8:56:57 AM9/10/19
to
On 9/10/19 12:00 AM, Melzzzzz wrote:
> On 2019-09-10, Daniel <daniel...@gmail.com> wrote:
>> Has anyone attempted to use stateful allocators with GCC basic_string?
>>
>> My attempts with versions up to 9 result in a compile time error
>>
>> /usr/include/c++/9/bits/basic_string.tcc:596:30: error: no matching function for call to ‘my_alloc::my_alloc()’
>> 596 | if (__n == 0 && __a == _Alloc())
>>
>> My example allocator my_alloc doesn't have a default constructor, which I don't think you would ever want on a stateful allocator. So why would GCC
>> want to compare the passed allocator __a with the default constructed
>> allocator _Alloc()?
>
> Don't know about allocator requirements, but if default constructor is
> not one of them it is a bug in gcc...

I couldn't find any such requirement.

Juha Nieminen

unread,
Sep 11, 2019, 5:04:43 AM9/11/19
to
Daniel <daniel...@gmail.com> wrote:
> I have no issues with vs or clang.

I tried this with clang, and it gives an error. (If the constructor is
commented out, it compiles and works ok.) Am I missing something obvious?

//-----------------------------------------------------
#include <iostream>
#include <string>

struct MyAlloc
{
using value_type = char;
MyAlloc(int) {}
char* allocate(std::size_t n) { return new char[n]; };
char* allocate(std::size_t n, const void*) { return new char[n]; };
void deallocate(char* ptr, std::size_t) { delete[] ptr; }
bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
};

int main(int argc, char** argv)
{
std::basic_string<char, std::char_traits<char>, MyAlloc> str("hello");
std::cout << str << "\n";
}
//-----------------------------------------------------

Daniel

unread,
Sep 11, 2019, 7:32:46 AM9/11/19
to
On Wednesday, September 11, 2019 at 5:04:43 AM UTC-4, Juha Nieminen wrote:
For a stateful allocator, you need to pass an instance of the constructor
to the object. But MyAlloc also isn't right, it needs to be a template class,
and have a constructor that supports rebinding. As a minimal example, try

#include <iostream>
#include <string>
#include <memory>

template <class T>
struct MyAlloc
{
using value_type = T;
using size_type = std::size_t;
using propagate_on_container_move_assignment = std::true_type;

MyAlloc(int) {}

template< class U >
MyAlloc(const MyAlloc<U>&) noexcept {}

T* allocate(size_type n)
{
return static_cast<T*>(::operator new(n * sizeof(T)));
}

void deallocate(T* ptr, size_type) noexcept
{
::operator delete(ptr);
}

bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
};

int main()
{
std::basic_string<char, std::char_traits<char>, MyAlloc<char>> str("hello", MyAlloc<char>(1));
std::cout << str << "\n";
}


Daniel

unread,
Sep 11, 2019, 7:39:59 AM9/11/19
to
On Tuesday, September 10, 2019 at 3:25:40 AM UTC-4, Öö Tiib wrote:

> Is it regression so someone had added the _Alloc() back,
> or are you using very old gcc?

I believe I'm using the correct versions of gcc in the travis builds, but I
think what's happening is that I'm picking up a version of the library that is
#if'ed compiled for gcc's old reference counting strings, viz

#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
if (__beg == __end && __a == _Alloc())
return _S_empty_rep()._M_refdata();
#endif


Manfred

unread,
Sep 11, 2019, 9:02:23 AM9/11/19
to
On 9/11/2019 1:32 PM, Daniel wrote:
> On Wednesday, September 11, 2019 at 5:04:43 AM UTC-4, Juha Nieminen wrote:
>> Daniel wrote:
>>> I have no issues with vs or clang.
>>
>> I tried this with clang, and it gives an error. (If the constructor is
>> commented out, it compiles and works ok.) Am I missing something obvious?
>>
>> //-----------------------------------------------------
>> #include <iostream>
>> #include <string>
>>
>> struct MyAlloc
>> {
>> using value_type = char;
>> MyAlloc(int) {}
>> char* allocate(std::size_t n) { return new char[n]; };
>> char* allocate(std::size_t n, const void*) { return new char[n]; };
>> void deallocate(char* ptr, std::size_t) { delete[] ptr; }
>> bool operator==(const MyAlloc&) const { return true; }
>> bool operator!=(const MyAlloc&) const { return false; }
>> };
>>
>> int main(int argc, char** argv)
>> {
>> std::basic_string<char, std::char_traits<char>, MyAlloc> str("hello");
>> std::cout << str << "\n";
>> }
>> //-----------------------------------------------------
>
> For a stateful allocator, you need to pass an instance of the constructor
> to the object.
You probably meant to pass an instance of the allocator.
In C++ an instance of the constructor is ungood.

Daniel

unread,
Sep 11, 2019, 9:33:49 AM9/11/19
to
On Wednesday, September 11, 2019 at 9:02:23 AM UTC-4, Manfred wrote:
> On 9/11/2019 1:32 PM, Daniel wrote:
> >
> > For a stateful allocator, you need to pass an instance of the constructor
> > to the object.
> You probably meant to pass an instance of the allocator.
> In C++ an instance of the constructor is ungood.
>
Indeed :-)

0 new messages