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?

Reply via email to