Fixing "toStringz"

monarch_dodra monarchdodra at gmail.com
Tue Aug 20 23:18:47 PDT 2013


I'm looking for advice on fixing "toStringz". The current 
implementation that accepts "immutable(char)[]" is:

immutable(char)* toStringz(string s) pure nothrow
{
     if (s.empty) return "".ptr;
     /* Peek past end of s[], if it's 0, no conversion necessary.
      * Note that the compiler will put a 0 past the end of static
      * strings, and the storage allocator will put a 0 past the 
end
      * of newly allocated char[]'s.
      */
     immutable p = s.ptr + s.length;
     // Is p dereferenceable? A simple test: if the p points to an
     // address multiple of 4, then conservatively assume the 
pointer
     // might be pointing to a new block of memory, which might be
     // unreadable. Otherwise, it's definitely pointing to valid
     // memory.
     if ((cast(size_t) p & 3) && *p == 0)
         return s.ptr;
     return toStringz(cast(const char[]) s);
}

The explanation is clear enough (I think). The problem with this 
approach is that nothing guarantees that, say, the current string 
is allocator allocated from a very large buffer, and the "past 
the end" \0 is not actually immutable (and will be changed when 
allocator allocates a new string).

Long story short, the function operates under wrong assumptions.

Since "being correct" > "performance", this needs to be 
corrected. I'm looking for ideas though on being able to detect 
if a string *is* a manifest constant string?

The solution doesn't necessarily have to work on all platforms, 
but if we can get something to work on some platforms, that would 
already be good.

ideas?


More information about the Digitalmars-d mailing list