Как обеспечить возврат функциями объектов переменной длины?
Наверняка большинство программистов при работе с языками более низкого уровня (типа Си) отмечало неудобство в пользовании функциями:
функции с удовольствием возвращают значения простейших типов данных,
но когда из функции надо возвратить что-то посложнее, то оказывается, что не всё так гладко.
Строку — одну из простейших вещей — можно возвратить только через указатель на неё.
Если размер строки не известен вовремя компиляции (что бывает весьма нередко),
то строку помещают в динамическую память («кучу»), а возвращают указатель на неё.
В языках типа PHP всё, казалось бы, проще: функции запросто возвращают строки: «return $string».
Но за этой внешней простотой кроется всё та же «куча»: строка хранится именно в «куче» и работают с ней через указатель.
С возвратом значений простейших типов всё понятно: функция помещает результат в регистр и возвращает управление.
Функция может даже возвратить какую-то структуру (а она имеет фиксированную длину),
но и это не решает главной проблемы языков со статической типизацией.
Функции не умеют возвращать объекты, длина которых известна только в момент вызова функции.
Но чем плоха практика размещения объекта переменной длины в динамической памяти?
Да тем, что эти операции «дороги» и не всегда безопасны
(см. Почему динамическое распределение памяти — это плохо).
Читаем далее следующую статью:
Типы переменного размера (dynamically sized types, DST) в языке Rust.
Почитайте ещё:
Опубликовано: 2014.07.27, последняя правка: 2018.10.29 15:54
Отзывы
✅ 2016/04/03 03:42, rst256 #0
Для строчек есть strdup, и куча иных функций в т.ч. со сборкой мусора✅ 2016/04/03 15:11, Автор сайта #1
Википедия:strdup — нестандартная функция языка программирования Си, создающая копию указанной нуль-терминированной строки в куче (используя malloc) и возвращающая указатель на неё. Вот именно, что в куче. Это же из пушки по воробьям. malloc — достаточно «дорогая» операция, и последующие статьи — как раз о том, как это сделать «дешевле».✅ 2016/08/07 10:46, rst256 #2
malloc неизбежен. Что мешает выделить через него кусок побольше и пользовать его аки стек? Всего то надо решить, какой объем ему установить или предусмотреть способы расширения или фрагментации. А если "возвращать" по значению, то как быть, если объект надо выше по цепочке вызовов передать? Его же содержимое придется через каждую функцию по цепочке тянуть по стеку вверх, копируя его содержимое. Особенно веселым представляю довольно распространенный случай, когда объект таки нужно длительное время хранить в памяти и последнее копирование, которое ему придется перенести, будет копирование на блок, выделенный из кучи :-)
Я внимательно изучил все статьи автора с пользу стека против кучи. Техническая сторона вопроса там хорошо проработана, но я не увидел там ни одного слова об синтаксисе связанном, с хранением объектов в стеке. Такое чувство, что там всё полностью будет автоматизированно. Значит, работать будет чуть хуже, чем malloc, у которого хотя бы есть один параметр (размер выделяемого блока). Как минимум требуется указать время жизни объекта, т.е. в каком месте стека будет он расположен Добавить свой отзыв
Написать автору можно на электронную почту mail(аt)compiler.su
|