On Friday, 17 September 2021 at 06:27:40 UTC, frame wrote:
Thanks, I'm just careful with casting.
Does it really allocate from a literal if it's used on the stack only? Is `-vgc` switch reliable?

looks to me like it calls

```d
// object
private U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T))
{
    if (__ctfe)
        return _dupCtfe!(T, U)(a);

    import core.stdc.string : memcpy;
    auto arr = _d_newarrayU(typeid(T[]), a.length);
memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * a.length);
    return *cast(U[]*) &arr;
}
```

->

```d
// rt.lifetime
extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t length) pure nothrow @weak
{
...
    auto info = __arrayAlloc(size, ti, tinext);
...
}
```

->

```d
// rt.lifetime
BlkInfo __arrayAlloc(size_t arrsize, const scope TypeInfo ti, const TypeInfo tinext) nothrow pure
{
...
    auto bi = GC.qalloc(padded_size, attr, tinext);
...
}
```

->

```d
// gc.impl.conservative.gc
BlkInfo qalloc( size_t size, uint bits, const TypeInfo ti) nothrow
    {

        if (!size)
        {
            return BlkInfo.init;
        }

        BlkInfo retval;

retval.base = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, retval.size, ti);

        if (!(bits & BlkAttr.NO_SCAN))
        {
            memset(retval.base + size, 0, retval.size - size);
        }

        retval.attr = bits;
        return retval;
    }
```

which you can also follow in an objdump. Conclusion: -vgc is missing this GC allocation.

To stack-allocate a mutable copy of a string literal go with

```d
@safe @nogc nothrow unittest {
    enum S = "hello world";
    char[S.length+1] s1 = S;
    char* s2 = &s1[0];

    // Normally you'd expect s1.ptr[s1.length] here,
// but the '\0' byte is explicitly part of s1 due to length+1 above.
    assert(s1[s1.length-1] == '\0');

    (() @trusted {
        import core.stdc.stdio : puts;
        import std.string : fromStringz;

        puts(s2);
        assert(s2.fromStringz == S);
    })();
}
```

Reply via email to