[sldev] Uses of LLString and std::string ?
Phoenix
phoenix at secondlife.com
Wed Jan 23 11:15:42 PST 2008
wow, I've never seen so many Lindens reply on a single thread. Guess
it shows you what makes a c++ nerd's ears perk. :)
Years ago, before open source, in the long ago time, there was
LLString. It was a very basic string implementation based on NULL
terminated char* which would dynamically resize on every operation.
After secretly using standard containers in our code base for a while
(they used to be forbidden according to our coding standards) to
prove they worked on all of our platforms, I began replacing all
instances of char* APIs with a std::string replacement and typically
using std::string and std::ostringstream for using and building strings.
This worked all right, but std::string has, as noted by Steve and in
my humble opinion, at least one fatal flaw -- constructing a
std::string with NULL crashes. The most mechanical transition to
reduce crashes was to replace all instances of std::string with
LLString and magically the crashes disappear.
Sadly, the LLString class is not a good use of inheritance and
introduces overhead when working with many c++ libraries -- even our
own. To make matters worse, at least one method does not work with
narrow and wide characters. All new APIs should be using std::string,
but the habit of using LLString is hard to break.
Personally, I always use std::string, and wrap char* and c APIs with
ll_safe_string which is prototyped as:
/**
* @brief Return a string constructed from in without crashing if the
* pointer is NULL.
*/
std::string ll_safe_string(const char* in);
What we cold really use is an LLString that provided native utf-8
support like gtk's ustring.
On 2008-01-23, at 10:08, Richard Nelson wrote:
> Keep in mind that LLString derives from std::string and can be used
> anywhere a std::string is. But, as Steve notes, you can't
> arbitrarily convert a reference to a std::string to a reference to
> a LLString, so any conversion back to LLString will involve a copy.
>
> Before any C++ purists complain, let me note that std::string does
> not have a virtual destructor and hence we can never add any member
> variables or implement a non-trivial destructor in LLString. It
> serves merely as a convenient wrapper for std::string that tests
> for the null char* case, as Steve mentioned, and provides some
> handy functions (e.g. case-insensitive string comparison) that
> would otherwise require boilerplate code.
>
> Note that all of the custom functions are implemented as statics,
> and not member functions. This is to support the ultimate goal of
> having LLString simply be a namespace for string helper functions
> that operate on std::strings.
>
> R.
>
> On Wed, 23 Jan 2008 08:52:22 -0800, Steve Linden
> <steve at lindenlab.com> wrote:
>
>> Correct, LLString exists specifically to protect against passing a
>> NULL char* to a function that takes a const std::string&. C++ will
>> quietly attempt to convert the NULL char* into a std::string
>> causing a crash.
>>
>> e.g.
>>
>> foo (const std::string& s)
>> {
>> }
>> bar (const char* c)
>> {
>> foo(c); // crashes if c is NULL
>> }
>> main()
>> {
>> const char* s = fetchSomeString(); // returns NULL if it fails
>> foo(s); // crash!
>> }
>>
>> Note: we -still- have thousands of char arrays and char*'s in the
>> code, and this pattern exists all over the place, especially in
>> the UI code. We are actively working on eliminating this pattern.
>> Once we do, we can safely replace LLString with std::string.
>>
>> Because of the expense of converting a std::string to a LLString,
>> we try to use LLString anywhere we will pass it as a std::string.
>> However, in the grand scheme of things this is unlikely to be a
>> significant performance bottleneck so we are not as paranoid about
>> it as we might be.
>>
>> -Steve
>>
>> Dave Parks wrote:
>>> I believe the point of LLString is to protect against NULL
>>> pointer assignments. It's legacy from a time when we used char*
>>> strings and began mixing in std::string. Assigning a standard
>>> string to NULL dereferences NULL, causing a crash. LLString
>>> protects against this by checking for NULL on assignment for
>>> char* strings.
>>>
>>> Alissa Sabre wrote:
>>>> I have a question.
>>>>
>>>> SL viewer uses two data types LLString and std::string, that are
>>>> almost identical. They are sometimes intermixed. LLString to
>>>> std::string conversion is by a simple upcasting, but the opposit
>>>> is by
>>>> a deep copy through a constructor that requires some overhead.
>>>>
>>>> What is the purpose of LLString? In case it has some, then the
>>>> next
>>>> question is why LL uses both LLString and std::string? (Cf. LL
>>>> never
>>>> uses C++ bool type.)
>>>>
>>>> Assuming there is a good reason to use both LLString and
>>>> std::string
>>>> in SL viewer, what is the criteria (or guidelines) to choose from
>>>> LLString and std::string?
>>>>
>>>> Alissa Sabre
>>>> --------------------------------------
>>>> Easy + Joy + Powerful = Yahoo! Bookmarks x Toolbar
>>>> http://pr.mail.yahoo.co.jp/toolbar/
>>>> _______________________________________________
>>>> Click here to unsubscribe or manage your list subscription:
>>>> /index.html
>>>>
>>>
>> _______________________________________________
>> Click here to unsubscribe or manage your list subscription:
>> /index.html
>
>
>
> --
> Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
> _______________________________________________
> Click here to unsubscribe or manage your list subscription:
> /index.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : http://lists.secondlife.com/pipermail/sldev/attachments/20080123/7f7cef18/PGP.pgp
More information about the SLDev
mailing list