Всем привет.
Раньше, когда люди спрашивали, чем плохо то, что функция возвращает строку, основным (и самым очевидным) доводом было лишнее копирование данных: т.е. сначала строка/массив копируется в стек при возврате значения из функции, затем ещё раз копируется из стека в другой массив, к которому идёт присваивание значения. Но, внезапно, для некоторых ленивых скриптеров это не аргумент...
Не так давно получилось найти новый изъян, который (может быть) переубедит ещё несколько скриптеров: баг с возвратом массивов, который может привести к неправильной работе сервера.
Допустим, у нас есть следующие две функции:
Довольно просто, так ведь? Есть глобальная строка, и есть функция, которая возвращает эту строку. И ещё есть другая функция, которая возвращает результат первой функции.
new global_string[12] = {"Hello world"}; StringOrigin() { return global_string; } ReturnString() { return StringOrigin(); }
Такой код работает вполне нормально. Нативная функция strcat() вызывает Pawn-функцию StringOrigin(), которая просто возвращает глобальную строку. Это первый "уровень" вложенности возврата массивов (strcat() -> StringOrigin()).
А вот такой код уже не работает. strcat() вызывает функцию ReturnString(), которая возвращает то, что ей возвращает StringOrigin(). Это второй "уровень" вложенности (strcat() -> ReturnString() -> StringOrigin()), и на нём уже проявляется ошибка.
При подключенном плагине CrashDetect выводится следующее сообщение:
Код:[debug] Run time error 5: "Invalid memory access"
Решение проблемы очень простое: всегда возвращайте строки через массив, переданный по ссылке.
new string[12] = {"Hello world"}; StringOrigin(output[], size = sizeof output) { return 0; // Будем считать, что 0 - код успешного выполнения этой функции. } ReturnString(output[], size = sizeof output) { return StringOrigin(output, size); // Нет ничего плохого в дальнейшем возврате возвращаемого значения // из StringOrigin(), т.к. это всего лишь одна ячейка (0), а не массив. }
Оригинал примера с возвратом строк: https://github.com/sampctl/pawn-array-return-bug
Перевод и дополнение: Daniel_Cortez
Специально для Pro-Pawn.ruКопирование данной статьи на других ресурсах без разрешения автора запрещено!