Boost logo

Boost :

From: Hervé Brönnimann (hervebronnimann_at_[hidden])
Date: 2007-12-04 05:36:04


Sorry for the double (triple) posting. My mailer crashed and I
started again with the draft, unaware that the post went through.

Jens: My post wasn't specific to the shared string implementation,
the original posting was. After all, Robert's code was working fine
with non-shared implementation.

> On Dec 4, 2007, at 5:13 AM, Jens Seidel wrote:
> To be honest, isn't a specific implementation not completely
> unimportant? You don't want to rely on implementation details, right?

I don't rely on gcc's string implementation details, but on whether a
string implementation is shared or not. The original problem and
argument I built upon it is true for any shared implementation. If
you think there's no way in C++ to tell whether a string class is
shared or not, think about Chuck's posting:

bool is_string_class_shared() {
     const std::string s1('x');
     const std::string s2(s1);
     *(const_cast<char*>s1.data()) = 'y';
     return s2[1] == 'y';
}

Speaking of the programming with only the C++ standard, it
specifically mentions allowing a shared implementation of std::string.

> There is only one solution: remove the buggy casting code and
> replace it
> with a proper one as suggested. Whether the proper one is slower or
> not
> is unimportant!

I strongly disagree. Performance of string serialization is
important, as Robert posted in a previous msg. For that reason, the
use of const_cast<char*>s.data() seems justified.

>> Seems to me, since you are going to rewrite your string anyway, you
>> might as well clear() it first, then resize(size). That'll take care
>> of creating a new representation. The problem with that is that it
>> will write over the string twice, first filling it with 0s then with
>> the read data. But think about it: if the string is shared, you
>> need to construct a new representation with the requested size
>> anyway, and it will have to be filled with 0s.
>
> No, the problem is that this is implementation specific. Don't rely on
> such stuff, rely on the C++ standard!

Again, my argumentation isn't implementation specific, it's true of
any shared string class.

My patch should work with any standard-compliant string. What I
argued was that it's better than the previously proposed fixes for
gcc's implementation. What I didn't argue was that it should also be
very efficient with non-shared implementation. If I had, I would've
noticed that for implementations which release memory upon clearing
or assignment, however, it will first free the capacity, then
reacquire it, an unnecessary operation. For non-shared
implementation, the resize(size) alone was sufficient, so I would
simply amend my previous posting by enclosing the "s = std::string
();" within a #if BOOST_SHARED_STD_STRING (suitably defined in
boost/config.hpp, and detected per platform using e.g. the code I
posted above).

--
Hervé Brönnimann
hervebronnimann_at_[hidden]
> On Tue, Dec 04, 2007 at 04:59:17AM -0500, Hervé Brönnimann wrote:
>> Inspection of the g++ string implementation (latest 4.1.x) shows that
>> resize() will *almost* always create a new rep and thus a new data()
>> for the string, if it is shared.  The only exception is when the
>> requested size == s.size().  Chuck, was this the bug that hit you?
>
>>
>
> Jens
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/ 
> listinfo.cgi/boost

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk