GC seems to crash my C-code function

jfondren julian.fondren at gmail.com
Fri Sep 17 06:58:01 UTC 2021


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);
     })();
}
```


More information about the Digitalmars-d-learn mailing list