std.string.toStringz 在 dlang 中如何工作?

How does std.string.toStringz work in dlang?

https://dlang.org/library/std/string/to_stringz.html

据我所知,它无法工作:

toStringz 在堆栈上创建一个数组并 returns 它的指针。 toStringzreturns后,栈上的数组被丢弃,指针失效

但我认为它确实有效,因为它是标准库的一部分。那么我对上面的理解有什么问题吗?

另一个相关问题:

函数签名中的scope return是什么意思?我访问了 https://dlang.org/spec/function.html 但没有找到 scope return

它不会在堆栈上创建数组。如有必要,它会在 GC 堆上分配一个新字符串。

该实现通过检查现有字符串的零终止符来工作 - 如果它认为可以在没有内存错误的情况下这样做(这是通过检查最后一个字节的对齐来猜测的。如果它是四的倍数,它不会冒险,但如果不是,它会在指针前读取一个字节,因为故障边界是四个间隔的倍数)。

如果那里已经有一个零字节,它 return 是未修改的输入。这就是签名中 return 的意思——它可能 return 相同的输入。 (这是一个刚刚记录的新功能......昨天。它甚至还没有合并:https://github.com/dlang/dlang.org/pull/2536 但是 stdlib 文档是从 master 分支重建的 lol)

无论如何,如果那里没有零字节,它会分配一个新的 GC 字符串,复制现有的字符串,附加零,然后 return 就是这样。这就是文档中的注释警告 C 函数保留它的原因。如果 C 函数让它无法执行,那么获取它的不是堆栈——而是 D 垃圾收集器。 D 的 GC 看不到 C 函数分配的内存(除非特别告知),并且会认为该字符串在下次运行时未被引用并因此释放它,从而导致释放后使用错误。

签名中的 scope 关键字是 D 检查这个顺便说一句的方式:这意味着参数将只在这个函数的范围内使用(尽管 return 的组合意味着它只会在此函数的范围内使用或 return 通过此函数编辑)。但那是在 toStringz 的输入上——您调用的 C 函数可能不使用 D 语言限制,因此它不会被自动捕获。

所以再总结一下属性:

scope - 参数不会离开函数的作用域。不会分配给全局或外部结构等

return - 参数可能 return 由函数编辑。

return scope - 以上的混合;它不会离开函数的范围,除非通过 return 值。