Как работает std.string.toStringz в Dlang? - PullRequest
0 голосов
/ 30 декабря 2018

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

В моем понимании это не могло работать:

toStringz создает массив в стеке и возвращает его указатель.После возврата toStringz массив в стеке отбрасывается и указатель становится недействительным.

Но я полагаю, что он действительно работает из-за того, что является частью стандартной библиотеки.Так что же не так в моем понимании вышесказанного?

Еще один связанный с этим вопрос:

Что означает scope return в сигнатуре этой функции?Я посетил https://dlang.org/spec/function.html, но там не нашел scope return.

1 Ответ

0 голосов
/ 30 декабря 2018

Не создает массив в стеке.При необходимости он выделяет новую строку в куче GC.

Реализация работает путем проверки существующей строки на нулевой терминатор - если она считает возможным сделать это без сбоя памяти (что можно предположить путем проверкивыравнивание последнего байта. Если он кратен четырем, он не рискует, но если это не так, он читает на один байт впереди указателя, потому что границы неисправностей кратны четырем интервалам).

Если там уже есть нулевой байт, он возвращает входные данные без изменений.Вот что означает return в подписи - она ​​может возвращать тот же самый ввод.(Это новая функция, которая только что была задокументирована ... вчера. И даже не объединена: https://github.com/dlang/dlang.org/pull/2536 Но документы stdlib перестроены из главной ветки lol)

В любом случае,если там нет нулевого байта, он выделяет новую строку GC, копирует существующую, добавляет ноль и возвращает ее.Вот почему примечание в документации предупреждает о том, что функция C хранит его.Если функция C удерживает его вне выполнения, его получит не стек, а D-сборщик мусора.GC D не может видеть память, выделенную функциями C (если специально не проинформирован об этом), и будет думать, что на строку не будет ссылаться в следующий раз, когда она будет запущена, и, таким образом, освободит ее, что приведет к ошибке использования после освобождения.

The *Ключевое слово 1012 * в сигнатуре - способ проверки этого пути между прочим: это означает, что аргумент будет использоваться только в области действия этой функции (хотя комбинация return означает, что он будет использоваться только в области действия этой функции ИЛИ, возвращенной через эту функцию),Но это на входе toStringz - вызываемая вами функция C, вероятно, не использует это ограничение языка D, и это не будет автоматически перехвачено.

Итак, чтобы снова суммировать атрибуты:

scope - аргумент не покинет область действия функции.Не присваивается глобальной или внешней структуре и т. Д.

return - аргумент может быть возвращен функцией.

return scope - гибрид вышеприведенного;он не покинет область видимости функции EXCEPT через возвращаемое значение.

...