This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c++/9733: Incorrect defintion for allocator<T>::allocate(size_t,void*)
- From: ortiza at ca dot ibm dot com
- To: gcc-gnats at gcc dot gnu dot org
- Cc: thomasl at ca dot ibm dot com
- Date: 17 Feb 2003 21:32:59 -0000
- Subject: c++/9733: Incorrect defintion for allocator<T>::allocate(size_t,void*)
- Reply-to: ortiza at ca dot ibm dot com
>Number: 9733
>Category: c++
>Synopsis: Incorrect defintion for allocator<T>::allocate(size_t,void*)
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 17 21:36:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Andrew Ortiz
>Release: gcc version 3.2
>Organization:
>Environment:
SuSe linux 2.4.19 on IBM PowerPC
>Description:
PROBLEM DESCRIPTION:
ISO/IEC 14882:1998(E) 20.1.5 Allocator Requirements Table 32.
2 member functions must be defined for Allocator.
T* a.allocate(n)
T* a.allocate(n,u)
where :
a = a value of type allocator<T>
u = a value of type allocator<void>::const_pointer
n = a value of type allocator<T>::size_type.
allocator<T> is defined in /usr/include/g++/bits/stl_alloc.h on Linux.
Linux accomplishes the above task by defining one allocate(n,u) member function which
takes 2 arguments with the second argument having a default value.
So the signature for allocate(n,u) is similiar to below.
template <class _Tp> class allocator
{
_Tp* allocate(size_type __n, const void* = 0) {...}
}
This allows invoking allocate() with 1 or 2 args, in either case the above signature would suffice.
The problem is, if a derived template class overrides allocate(n,u) and *does not use* a default value
for argument 2, then allocate(n) will not be found.
So I derived from allocator<T> expecting that there are 2 member functions allocate(n) and allocate(n,u).
I only want to override allocate(n,u) in my derived template class. The signature is similiar to below:
template <class _Tp> class My_alloc : public std::allocator<T>
{
_Tp* allocate(size_type __n, const void*) {...}
}
So far this is ANSI compliant. The signature for allocate(n,u) in our derived template
class *does not use* a default value for argument 2, we have problems.
No version of allocate(n) exists in the base template class or derived template class.
Because vector<>() tries to invoke My_alloc<t>::allocate(n), the testcase cannot compile.
>How-To-Repeat:
STEPS TO REPRODUCE THE PROBLEMS:
---------------------------------------------------------------------------
# 1. README.ksh
#!/usr/bin/ksh
g++ -o a.o a2.cpp
echo Return code: $?
---------------------------------------------------------------------------
/**** 2. a2.cpp ****/
#include <vector>
template<class T>
class Myalloc_2 : public std:: allocator<T> {
public:
typename std:: allocator<T>::pointer
allocate(typename std:: allocator<T>::size_type N,
typename std:: allocator<void>::const_pointer P) /* ".... P=0)" works*/
{
std:: allocator<char> a ;
return (a.allocate(N, P));
}
void deallocate(typename std:: allocator<T>::pointer P, typename std:: allocator<T>::size_type N)
{
std:: allocator<char> a ;
a.deallocate(P, 1);
}
template <class Z> struct rebind
{
typedef Myalloc_2<Z> other;
};
};
typedef Myalloc_2<char> use_type;
int main(int argc, char *argv[])
{
use_type al;
std:: vector<char, use_type > v4(5, (char)'x', al);
}
--------------------------------------------------------------------------
EXPECTED OUTPUT:
Return code: 0
ACTUAL OUTPUT:
/usr/include/c++/3.2/bits/stl_vector.h: In member function `_Tp* std::_Vector_alloc_base<_Tp, _Allocator,
_IsStatic>::_M_allocate(unsigned int) [with _Tp = char, _Allocator =
use_type, bool _IsStatic = false]':
/usr/include/c++/3.2/bits/stl_vector.h:138: instantiated from `std::_Vector_base<_Tp, _Alloc>::_Vector_base(unsigned int, std::_Vector_alloc_base<_Tp, _Alloc, std::_Alloc_traits<_Tp, _Allocator>::_S_instanceless>::allocator_type&) [with _Tp = char, _Alloc = use_type]'
/usr/include/c++/3.2/bits/stl_vector.h:338: instantiated from `std::vector<_Tp, _Alloc>::vector(unsigned int, const _Tp&, std::_Vector_base<_Tp, _Alloc>::allocator_type&) [with _Tp = char, _Alloc = use_type]'
a2.cpp:30: instantiated from here
/usr/include/c++/3.2/bits/stl_vector.h:96: no matching function for call to `Myalloc_2<char>::allocate(size_t&)'
a2.cpp:11: candidates are: std::allocator<_Alloc>::pointer
Myalloc_2<T>::allocate(std::allocator<_Alloc>::size_type, const void*) [with
T = char]
Return code: 1
>Fix:
Supply member function allocator<T>::allocate(n){}; in /usr/include/g++/bits/stl_alloc.h
>Release-Note:
>Audit-Trail:
>Unformatted: