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