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?