Thread: RE: std::vector::clear (was: [GD-Windows] VS.net rants, was Re: VC++ lag)
Brought to you by:
vexxed72
From: Paul B. <pa...@mi...> - 2003-06-14 16:16:59
|
=20 I'm not arguing for/against the change in VC7, but I read through good chunks of the standard last night and found only a couple references to the requirements of clear(). And each of those was in context of running time and not implementation. =20 Is there a particular part of the standard that clearly says that clear *must be implemented* as erase(begin(), end())? =20 Moreover, the point of standards (especially the C++ standard) is as much what they say and what they *do not* say. Your argument that since it doesn't explicitly say clear() deallocates means that it should not is wrong. There is a clear language in the standard of phrases like "should have" and "must have" and such that have well defined meanings. Lack of specification is exactly that - something the=20 standard fails to specify. =20 =20 A similar argument used to occur with list<>::size() being O(N) on=20 one implementation and O(1) on just about nearly every other=20 implementation. =20 =20 Luckily the next round of C++ standards (probably around 2020 at the current pace) should clearly define more implementation=20 requirements of the STL, but I still doubt they will define allocation deallocation requirements. =20 Paul =20 ________________________________ From: gam...@li... on behalf of Neil = Stewart Sent: Sat 6/14/2003 6:25 AM To: gam...@li... Subject: Re: std::vector::clear (was: [GD-Windows] VS.net rants, was Re: = VC++ lag) > I think ::swap() is a lame way to "deallocate" a vector's > memory. It requires creating a temporary vector, swapping > contents with the vector whose buffer you want to throw away, > and then clobbering the temporary vector. I find the idea > of having to summon up a trashcan, trading its emptiness > with the trash of another, and then destroying the trashcan > is nutty! > > The vector class should have had a ::deallocate() method from > the very beginning. Yes it is lame and a deallocate() method, or something like it, would = have been better. > Since it did not, and the ::swap() technique is lame, and > clobbering the owner of vector instances is lame, and adding > a new method to vector is lame, the least-lame option > is to exploit the lack of implementation specification of > ::clear(). My other post gives several reasons why this is a bad thing and, as I = said, I don't think there is a lack of specification in the standard on this matter, something which is reflected in all the STLs I have seen, except = for the one in VC7. The least lame option would be to leave things as they are for now, and = fix the problem in the forthcoming, new standard, but by adding something = like deallocate() and not changing clear(). > Sure, existing applications will suffer a speed hit when > recompiled, but the fix is as easy as searching for > "clear()" and replacing with "resize(0)". > > I know that the "ease of fixing" is not a justification for > changing the historical implementation! You're right, it's not a justification, so it isn't acceptable to just change things and hope everyone realises that what they thought was true = is actually not the case. Think of all the C++ web pages out there, all the books, and all the programmers that are working to an assumption = (actually, a specification) which is not being followed properly. It seems to me = that getting all of them to change is far more of an issue than sticking to = the accepted implementation and well-known swap() method for releasing the memory. > I think the new implementation of clear has a few benefits: > > (1) Reduce memory waste due to vectors keeping up to > (2 * max_bytes_needed) over their lifetimes; Well, apart from the fact that people already know how to free the = memory used by a vector (the swap method), this won't work, because only one implementation does this. It's a worthless feature, because you cannot = rely on it. > (2) Make crashing due to stale pointers and references > more likely! As it was(/is), when one did a clear() > of a vector, pointers to elements would still work > until the vector grew! With a ::clear() that > deallocates, the probability of discovering stale > pointers and references increases. I think you already know that this is a pretty ropey justification. ;) > (3) Custom allocators and deallocators will now have a > better sense of actual required memory on an > ongoing basis. What makes you think that? > As far as I'm concerned, the idea of something only growing > and never shrinking sounds like a black hole or a memory > leak! Well, you shouldn't be using vector then. That's what it is supposed to = do, and it's a very useful idiom for many applications. > I think Microsoft faced tough choices: > (a) Do nothing, and suffer the ever-expanding memory > consumption of vectors scattered all over code; Or do nothing and - shock, horror - remain identical to every other implementation. - Neil. ------------------------------------------------------- This SF.NET email is sponsored by: eBay Great deals on office technology -- on eBay now! Click here: http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5 _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=3D555 |
From: Neil S. <ne...@st...> - 2003-06-16 13:04:03
|
> It does specify the runtime behavior of push_back(), and it specifies > what program-visible state (using the standards library) is changed > through the function. If the contents of drive C is not program > visible using only the standards libraries, and you can format that > in the expected amortized runtime of push_back(), then that would be > a conformant (though useless) implementation. So it seems like the best thing you can do is give up any hope of this ever being sorted out and just write your own containers, and pretty much everything else. What a waste of effort... > Anyway, C++ is the new COBOL. How do you figure? - Neil. ________________________________________________________________________ This email has been scanned for all viruses by the MessageLabs Email Security System. For more information on a proactive email security service working around the clock, around the globe, visit http://www.messagelabs.com ________________________________________________________________________ |
From: Rich <leg...@xm...> - 2003-06-16 18:05:34
|
In article <005e01c33214$9c9b8b40$0100a8c0@r0x0rz>, "Neil Stewart" <ne...@r0...> writes: > 2. While the standard does not appear to say that erase() must not > deallocate memory, it very explicitly states that insert() will allocate > memory if required, and it is also very clear that resize() and reserve() > should never reduce capacity() (i.e. deallocate memory). Right. This is why I was saying you should do resize(0) if you want to retain the memory. I'm not a C++ language lawyer, but resize(0) more explicitly tells me as a reader of the code that they wanted to retain the current allocation but forget all the elements. clear() to me says that its OK to delete the current allocation as well as forget all the elements. -- "The Direct3D Graphics Pipeline"-- code samples, sample chapter, FAQ: <http://www.xmission.com/~legalize/book/> izfree: Open source tools for Windows Installer <http://izfree.sourceforge.net> |
From: Neil S. <ne...@r0...> - 2003-06-16 21:14:18
|
> Right. This is why I was saying you should do resize(0) if you want > to retain the memory. I'm not a C++ language lawyer, but resize(0) > more explicitly tells me as a reader of the code that they wanted to > retain the current allocation but forget all the elements. clear() to > me says that its OK to delete the current allocation as well as forget > all the elements. Well, if you have followed the last few messages on this subject, you will be aware that doing resize(0) is also no use (in terms of avoiding allocation & deallocation), as there is nothing in the standard that says that the implementor cannot realocate the memory elsewhere, so long as capacity() is greater or equal to what it was previously. You might say that it's illogical for them to do that, but I would have said that (and still *do* say that) about making clear() deallocate, and I'm far from the only one. Oh, and they can format drive C while they're at it. ;) So write your own, boys and girls, because the lunatics took over the asylum. - Neil. |
From: Tom H. <to...@ve...> - 2003-06-16 21:41:26
|
At 02:14 PM 6/16/2003, you wrote: >So write your own, boys and girls, because the lunatics took over the >asylum. Or you could follow these simple steps: 1. File a bug report with MS. 2. Use STLPort on all the platforms you support. 3. Let others know of the problem (and blast MS in the process if that's what you feel like doing) 4. Get on with your life, write code, finish your game. Tom |
From: Neil S. <ne...@r0...> - 2003-06-16 22:02:17
|
> Or you could follow these simple steps: > > 1. File a bug report with MS. > 2. Use STLPort on all the platforms you support. > 3. Let others know of the problem (and blast MS in the process if that's > what you feel like doing) > 4. Get on with your life, write code, finish your game. Only step 4 seems 'simple', so I think I'll do that, thanks. - Neil. |
From: Neil S. <ne...@r0...> - 2003-06-14 19:49:16
|
> Is there a particular part of the standard that clearly says that clear > *must be implemented* as erase(begin(), end())? It's at section 23.1.1 [lib.sequence.reqmts], and it clearly shows this as a requirement for sequences, which therefore covers vector. > Moreover, the point of standards (especially the C++ standard) is as > much what they say and what they *do not* say. Your argument that > since it doesn't explicitly say clear() deallocates means that it should > not is wrong. There is a clear language in the standard of phrases > like "should have" and "must have" and such that have well defined > meanings. Lack of specification is exactly that - something the > standard fails to specify. Sorry, but this is nonsense. You are suggesting that anything the standard does not forbid explicitly is "fair game". The standard does not specify that, under no circumstances, should vector::push_back() format drive C. Are you suggesting that an implementation should therefore be allowed to interpret this as a legal implementation detail? What happens is that people read meanings into things which are not really there in order to support their own arguments, so common sense has to prevail at some point. In this case, common sense settled on "no deallocation" quite some time ago, and then someone came along and threw that in the bin because it didn't suit their own requirements. > A similar argument used to occur with list<>::size() being O(N) on > one implementation and O(1) on just about nearly every other > implementation. Doesn't surprise me. What was the outcome of this one? > Luckily the next round of C++ standards (probably around 2020 at > the current pace) should clearly define more implementation > requirements of the STL, but I still doubt they will define allocation > deallocation requirements. I find it sad that the next standard is likely to be an order of magnitude more complex, not due to new content, but mainly due to tightening up of the language used to stop people taking liberties where it is pretty clear what was meant in the first place. - Neil. |
From: Jon W. <hp...@mi...> - 2003-06-14 23:40:43
|
> Sorry, but this is nonsense. You are suggesting that anything the = standard > does not forbid explicitly is "fair game". The standard does not = specify > that, under no circumstances, should vector::push_back() format=20 > drive C. Are It does specify the runtime behavior of push_back(), and it specifies=20 what program-visible state (using the standards library) is changed=20 through the function. If the contents of drive C is not program=20 visible using only the standards libraries, and you can format that=20 in the expected amortized runtime of push_back(), then that would be=20 a conformant (though useless) implementation. Anyway, C++ is the new COBOL. Cheers, / h+ |