On Saturday, 24 June 2017 at 13:11:02 UTC, Stefan Koch wrote:
On Saturday, 24 June 2017 at 12:22:54 UTC, Petar Kirov [ZombineDev] wrote:
[ ... ]

/**
 * Returns:
 * A pointer to a null-terminated string in O(1) time,
 * (with regards to the length of the string and the required
 * memory, if any) or `null` if  * the time constraint
 * can't be met.
 */
immutable(T)* fastStringZ(T)(return immutable(T)[] s) @trusted
if (isSomeChar!T)
{
    if (isStaticallyAllocated(s) && s.ptr[s.length] == 0)
        return s.ptr;
    else
        return null;
}
---

(Without `isStaticallyAllocated`, `fastStringZ` may *appear* to
work but if you pass the pointer to e.g. a C library and that
library keeps it after the call has completed, good luck tracking memory corruption if the slice was pointing to automatic/dynamic memory - e.g. static array buffer on the stack or GC / RC * heap
allocation.
* malloc or custom allocator + smart pointer wrapper)

Please note that not all static immutable strings have to be null terminated. It is possible to generate a string at ctfe which may appear the same as string literal, but does not have the \0 at the end.

But in that case, the check `s.ptr[s.length] == 0` in fastStringZ
would do the trick, right?

BTW, are you sure? AFAIU, it doesn't matter if the CTFE engine returns a non-null-terminated string expression, since the backend or the glue layer would write it to the object file as if it was a null-terminated string. But you're right if you mean that this trick won't work in CTFE, since
the `s.ptr[s.length] == 0` trick rightfully is disallowed.

---
void main()
{
    static immutable str = generateString();
pragma (msg, str, " is null-terminated at CT: ", str.isNullTerminated());

    import std.stdio;
writeln(str, " is null-terminated at RT: ", str.isNullTerminated());
}

string generateString()
{
    string res;
    foreach (i; 0 .. 26) res ~= 'a' + i;
    return res;
}

import std.traits : isSomeChar;

bool isNullTerminated(T)(scope const T[] str)
if (isSomeChar!T)
{
    if (!__ctfe)
        return str.ptr[str.length] == 0;
    else
        return false;
}
---

Compilation output:
abcdefghijklmnopqrstuvwxyz is null-terminated at CT: false

Application output:
abcdefghijklmnopqrstuvwxyz is null-terminated at RT: true


Reply via email to