uClibc++: bug in map::operator[]

Olivier Hochreutiner olivier.hochreutiner at gmail.com
Tue Apr 7 05:59:05 UTC 2009


> Would be nice to know what the conclusion was and if there are patches
> available if needed.

Here is Garrett's answer:


---------- Forwarded message ----------
From: Garrett Kajmowicz <ucxx at garrett.dyndns.biz>
Date: Fri, Apr 3, 2009 at 3:54 PM
Subject: Re: Fwd: uClibc++: bug in map::operator[]
To: Olivier Hochreutiner <olivier.hochreutiner at gmail.com>


On Friday 03 April 2009 02:35:26 am you wrote:
> Hi there,
>
> I am facing a problem with the uClibc++ implementation of std::map,
> which can be illustrated with the following code:

Hmm.  This is a very interesting problem.

The semantics that you describe are the ones which make sense - we shouldn't
be creating extra objects if they are unneeded.

On the other hand, what is currently being done is what the spec requires.
So, what to do?

I've decided to alter the library to make the semantics more consistent.

The change is currently in the SVN repository.

-     Garrett

>
> <-----------SNIP----------->
> #include <cstdio>
> #include <map>
>
> class my_type
> {
> public:
>        my_type() : id(count++) { printf("my_type() %d\n", id); }
>
>    void test() { printf("test() %d\n", id); }
>
>        int id;
>        static int count;
> };
>
> int my_type::count = 0;
>
> int main()
> {
>    std::map<int, my_type> mymap;
>    mymap[1].test();
>    mymap[1].test();
> }
> <-----------SNIP----------->
>
> I expect the output of the above code to be:
> my_type() 0
> test() 0
> test() 0
>
>
> i.e. a my_type object is constructed during the first call to
> map::operator[]. The second call should just return a reference to the
> object but not construct a new one. The above output is what I get
> with libstdc++ and visual studio 2005. With uClibc++ however, I get:
>
> my_type() 0
> test() 0
> my_type() 1
> test() 0
>
> i.e. a second my_type object is constructed during the second call to
> operator[], but the correct instance (the one constructed during the
> first call) is returned. I've had a look to uClibc++'s map::operator[]
> and it looks like this:
>
> <-----------SNIP----------->
>        reference operator[](const key_type& k){
>                //This is from the spec and is quite ugly.
>                return (*((insert(make_pair(k, T()))).first)).second;
>        }
> <-----------SNIP----------->
>
> The problem is, 'T()'  will construct a new object regardless of
> whether the key 'k' exists in the map or not.
>
> In most situations, this behaviour does not pose any problem. But in
> some cases, it can have side effects (as in the example above).
>
> I've seen that this implementation of operator[] was introduced in
> commit 9655, but the old code was working as expected, so IMO it
> should be reverted.
>
> In addition, is this code really in ISO/IEC 14882:1998 as the comment
> suggests ? It is referenced at
> http://www.sgi.com/tech/stl/Map.html
> and
> http://www.cplusplus.com/reference/stl/map/operator%5B%5D.html
> but is this conform to what ISO says ?
>
> Thanks,
>
> Olivier Hochreutiner


More information about the uClibc mailing list