From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28779 invoked by alias); 17 Feb 2003 21:36:00 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 28757 invoked by uid 71); 17 Feb 2003 21:36:00 -0000 Resent-Date: 17 Feb 2003 21:36:00 -0000 Resent-Message-ID: <20030217213600.28756.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org, thomasl@ca.ibm.com Resent-Reply-To: gcc-gnats@gcc.gnu.org, ortiza@ca.ibm.com Received: (qmail 27863 invoked by uid 48); 17 Feb 2003 21:32:59 -0000 Message-Id: <20030217213259.27862.qmail@sources.redhat.com> Date: Mon, 17 Feb 2003 21:36:00 -0000 From: ortiza@ca.ibm.com Reply-To: ortiza@ca.ibm.com To: gcc-gnats@gcc.gnu.org Cc: thomasl@ca.ibm.com X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) X-GNATS-Notify: thomasl@ca.ibm.com Subject: c++/9733: Incorrect defintion for allocator::allocate(size_t,void*) X-SW-Source: 2003-02/txt/msg00736.txt.bz2 List-Id: >Number: 9733 >Category: c++ >Synopsis: Incorrect defintion for allocator::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 u = a value of type allocator::const_pointer n = a value of type allocator::size_type. allocator 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 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 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 My_alloc : public std::allocator { _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::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 template class Myalloc_2 : public std:: allocator { public: typename std:: allocator::pointer allocate(typename std:: allocator::size_type N, typename std:: allocator::const_pointer P) /* ".... P=0)" works*/ { std:: allocator a ; return (a.allocate(N, P)); } void deallocate(typename std:: allocator::pointer P, typename std:: allocator::size_type N) { std:: allocator a ; a.deallocate(P, 1); } template struct rebind { typedef Myalloc_2 other; }; }; typedef Myalloc_2 use_type; int main(int argc, char *argv[]) { use_type al; std:: vector 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::allocate(size_t&)' a2.cpp:11: candidates are: std::allocator<_Alloc>::pointer Myalloc_2::allocate(std::allocator<_Alloc>::size_type, const void*) [with T = char] Return code: 1 >Fix: Supply member function allocator::allocate(n){}; in /usr/include/g++/bits/stl_alloc.h >Release-Note: >Audit-Trail: >Unformatted: