[sldev] Uses of LLString and std::string ?

Richard Nelson richard at lindenlab.com
Wed Jan 23 12:53:03 PST 2008


My final bit of clarification.  LLString, as Phoenix said, used to be a  
hand-rolled resizable string.  Once we decided to use std::string I  
stepped in to completely replace all existing uses of LLString.  I did  
this by changing LLString over to inherit from std::string, reimplementing  
it's methods in terms of std::string, and one by one replacing calls to  
LLString::ll_custom_method to the std equivalent, with the goal of adding  
a final "typedef std::string LLString" or a simple search and replace to  
finish the conversion process.  Sounded good in theory, but of course  
there was a hitch, the NULL assignment issue in this case.  In retrospect  
I should have added something like ll_safe_string at that point in time  
and completed the process, but it had moved beyond what I could do with a  
simple search and replace, so I stopped there, perhaps unwisely.

So that's where we stand today, a bunch of code that relies on an almost  
deprecated class.  In case anyone was still considering writing new code  
that uses LLStrings...

I think it would make sense to complete the process by finding all char*  
to LLString conversions and using ll_safe_string instead.

R.

On Wed, 23 Jan 2008 11:15:42 -0800, Phoenix <phoenix at secondlife.com> wrote:

> 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
>



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


More information about the SLDev mailing list