[sldev] Uses of LLString and std::string ?
Dzonatas
dzonatas at dzonux.net
Fri Jan 25 08:50:30 PST 2008
Phoenix wrote:
> 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);
>
I find it odd not to use a namespace with C++. An example with namespace
is LL::safe_string(), but the function is ll_safe_string() without the
namespace. If there is inertia to update code, then perhaps add in the
effect of the namespace to make it easier for non LL namespaces to exist
in the open source instead of forcing it all in one global namespace.
>
>>
>> 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.
That is not only a compiler bug, but it is also a programmer bug as
well. The compiler (especially MSVS) allows one to break the rules of
distinct types when it comes to char*. Perhaps, it was placed in the
compiler to allow easy movement from C to C++, but it is truly a bad
programmer bit.
The fact that the compiler didn't error at compiler-time on "foo(s)" is
the gotcha. Just because the compiler doesn't error at compile-time on
it doesn't mean that it is written correctly!
The fix would be to add this:
foo(const char* s)
{
foo( ll_safe_string( s ) ) ;
}
With strictness of distinct types, the compiler will choose the the
foo(char*) version when it encounters "foo(s)" in main().
With this extra function being defined, it would be correct for the
compiler to complain about unresolved references or detect that
foo(const char*s) was not defined. In fact, in a cross-compile
environment we find this strictness is enabled:
http://jira.secondlife.com/browse/VWR-186
Hence, the compiler really shouldn't try to convert char* automatically
to std::string by default. It should error. (And, now you know the pain
of why it shouldn't -- the crashes.)
Didn't mean to derail this conversation about LLString, but I noticed
this came up in the agenda:
http://wiki.secondlife.com/wiki/Open_Source_Meeting/2008-01-17
More information about the SLDev
mailing list