What's the fastest way to check if a slice points to static data
via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Jun 24 07:11:50 PDT 2017
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
More information about the Digitalmars-d-learn
mailing list