toStringz documentation is clear on why, when, and how to extend the lifetime of a D string:

  https://dlang.org/phobos/std_string.html#.toStringz

Assume foo is a D library function that passes a "string" result to e.g. C:

extern(C)
void foo(ref const(char) * name) {
  name = format!"file%s.txt"(42).toStringz;  // Allocates from GC memory
}

This may be fine for "immediate use" on the C side because at first glance no garbage collection can take place between our returning the result and their using it:

// C caller:
  const char * name = NULL;
  foo(&name);                 // Calls us
  printf("%s", name);         // Uses 'name' immediately

Is it really safe? Imagine a multi-threaded environment where another D function is executed that triggers a GC collection right before the printf.

Does the GC see that local variable 'name' that is on the C side? What I don't know is whether the GC is aware only of the stack frames of D functions or the entire thread, which would include the C caller's 'name'.

Ali

Reply via email to