PDA

Просмотр полной версии : [Урок] Самые известные баги компилятора



L0ndl3m
08.07.2014, 17:45
Введение

Самые известные баги стандартного компилятора "Pawno" и их исправление.

1)

Код


return "Some string";


Проблема
Возвращая строки напрямую компилятор падает ( краш ).

Решение
Создайте для вашей строки массив, далее возвратите её ( не рекомендуется возвращать большие строки ).


static const
some_text[] = "Some String";

return some_text;


2)

Код


string = (a == 5) ? "это пять" : "это не пять";


Проблема
Строки конкатенируются (объединяются, соединяются) компилятором в одну, например это будет скомпилировано в одну строку "Hello World":


string = "Hello" " " "World";


Однако компилятор на засчитывает ":" как часть тернарного оператора и компилятор засчитывает это за ошибку скриптера. Обычно в таких случаях ( а обычно это так и есть ) появляется вот такая ошибка:


<path>\errors.pwn(11) : error 001: expected token: "-string end-", but found "-identifier-"
Pawn compiler 3.2.3664 Copyright (c) 1997-2006, ITB CompuPhase
1 Error.


Решение
Чтобы это исправить, просто заключите строки в круглые скобки, хочу заметить, что на работоспособность кода это никак не влияет.


string = (a == 5) ? ("это пять") : ("это не пять");


3)
Код


new
gGlobalVariable = SomeFunction();


Проблема
Вызывая функцию для инициализации глобальной переменной компилятор падает ( краш ).

Решение
Вызовите функцию для инициализации переменной в "OnGameModeInit", "OnFilterScriptInit", или "main":


new
gGlobalVariable;

public OnGameModeInit()
{
gGlobalVariable = SomeFunction();
// некоторый код
}


4)
Код
Необязателен.

Проблема
Максимальная длина строки в компиляторе 512 символов ( считая с завершающим символом '\0' ).

Решение
Сократить текст со строкой. Обычно люди делают это так:


format(str, sizeof(str),
"Очень длинная строка",
other,
parameters);


Это разделяет вызов функции на 4 строки, делая её короче. Однако это решение далеко не хорошее. Даже иногда может откуда не возьмись возникнуть падения компилятора ( краш ).

5)
Код


new
gVar;

stock SomeFunction()
{
#if defined main
gVar = (gVar ? 0 : 1);
#endif

return 1;
}

main()
{
return SomeFunction() ? 0 : 1;
}


Проблема
Данный код будет генерироваться следующим образом: Сначала сгенерируется код в функции ( SomeFunction ), далее сгенерируется код в main (изначально компилятор "не знает", что "main" инициализируется позже). В результате, по неизвестной причине, любые другие тернарные операторы в вашем скрипте неверно сгенерируются и это приведёт к падению компилятора ( краш ).

Решение
Не используйте тернарный оператор для проверки на существование функции если функция ещё не определена или будет определена позже.

Автор урока: Y_Less
Перевод и дополнение: Londlem (http://pro-pawn.ru/member.php?2057-Londlem)
Оригинал: http://forum.sa-mp.com/showthread.php?t=355877 (http://forum.sa-mp.com/showthread.php?t=355877)

Специально для: Pro-Pawn.Ru (http://pro-pawn.ru)

Копирование данной статьи без разрешения автора запрещено!