"Неофициальный" релиз 3.10.10+ от 02.05.2021.
Скачать: https://www.dropbox.com/s/v5gvuwi0s2...0.10x.zip?dl=1
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-st...3.7-R2-1-1.zip
Исходный код: https://github.com/Daniel-Cortez/paw...e/master-fixes
Изменения с момента предыдущего релиза:
- Добавлены новые диагностики для обнаружения бесконечных циклов:
- warning 250: variable "%s" used in loop condition not modified in loop body
Буквально переводится как "переменная, используемая в условии цикла, не модифицируется в теле цикла".
Помогает обнаружить ошибки, когда пользователь забыл сделать инкремент/декремент счётчика цикла.
new i = 0; while (i < 10) // warning 250: variable "i" used in loop condition not modified in loop body DoSomething(i);- warning 251: none of the variables used in loop condition are modified in loop body
Переводится как "ни одна из переменных, используемых в условии цикла, не модифицируется в теле цикла".
То же самое, что и предыдущая диагностика, но срабатывает, когда в условии цикла используется несколько переменных - в таких случаях компилятор не может знать, какая именно переменная является счётчиком цикла, потому и возникла необходимость сделать отдельный варнинг с другой формулировкой.
for (new m = 0, n = 10; m < n; ) // warning 251: none of the variables used in loop condition are modified in loop body DoSomething(m);
- Исправлен баг, из-за которого при операциях инкремента/декремента ("++" и "--", как в пре-, так и в постфиксной форме) компилятор не регистрировал изменение значения в переменных и массивах и выдавал ложное предупреждение "warning 214: possibly a "const" array argument was intended".
ClearString(arr[]) { arr[0]++; // В массиве arr[] было изменено значение, однако компилятор всё равно предлагал // заменить "arr[]" в заголовке функции на "const arr[]". } // warning 214: possibly a "const" array argument was intended (symbol "arr")
- Исправлена неправильная кодогенерация для вариативных аргументов функций (как, например, в printf() или format()), модифицируемых с помощью операторов "++" и "--".
- Введены более строгие правила для заголовков функций (т.е. как для объявлений, так и для определений):
Цель новых правил - исключить труднодиагностируемые случаи, когда классовые спецификаторы не имеют эффекта или приводят к неправильной кодогенерации (см. #621, #624).
- Если в заголовке присутствует спецификатор класса, то определение функции тоже должно содержать этот спецификатор.
forward Func1(); public Func1(); // Введён классовый спецификатор "public"; компилятор будет требовать его в определении функции. Func1(); // OK (введённые ранее классовые спецификаторы являются обязательными только в определении, // в повторных объявлениях их можно пропустить). Func1(){} // Ошибка (нет спецификатора "public"). static Func2(); // Введён спецификатор "static". forward stock Func2(); // Введён спецификатор "stock"; теперь определение должно содержать // оба ключевых слова - как "static", так и "stock". stock static Func2(){} // OK (оба спецификатора на месте).- Повторные forward-объявления после определения функции не могут вводить новые классовые спецификаторы.
stock Func(){} // После определения функция "финализирована", введение новых спецификаторов запрещено. forward public Func(); // Ошибка (функция не была объявлена как "public").
- Исправлен баг, из-за которого в forward-объявлениях компилятор ожидал тег функции перед классовыми спецификаторами.
// Такое объявление компилируется без ошибок, как и положено forward public Func(); // Однако с тегом компилятор уже считал заголовок функции неправильным forward public Tag:Func(); // error 010: invalid function or declaration // В то время, как такой заголовок, на удивление, компилировался без ошибок forward Tag:public Func();- Исправлен недочёт с отсутствием поддержки 2 и более классовых спецификаторов в forward-объявлениях.
// Такое объявление компилировалось без ошибок. forward static Func1(); // Однако такое приводило к ошибке "error 010: invalid function or declaration" forward static stock Func2();- Исправлен недочёт, из-за которого компилятор не прерывал компиляцию, если точка входа в скрипт (функция main()) объявлена, но не реализована.
main(); // Функция main() объявлена, но не реализована. Из-за недочёта такой скрипт // компилировался без единой ошибки, но с неправильной точкой входа.- Исправлен баг, из-за которого компилятор позволял объявлять со спецификатором static переменные, названия которых начинаются на "@".
// Комбинация спецификаторов "public" и "static" в заголовках функций // считается неправильной, т.к. public-функция не может быть статической. static public Func1(){} // error 042: invalid combination of class specifiers // Имя, начинающееся на "@", означает, что функция/переменная с таким именем // является публичной, как если бы она была объявлена со спецификатором "public". // Соответственно, комбинация из имени на "@" и спецификатора "static" тоже // считается неправильной. static @Func2(){} // error 042: invalid combination of class specifiers // Однако из-за недочёта компилятор пропускал такую комбинацию для переменных. static @var = 0;- Теперь компилятор выводит warning 231 ("state specification on forward declaration is ignored") для объявлений функций не только в новом, но и в старом стиле (без ключевого слова forward).
// Суть warning 231 в том, что спецификации состояний автоматонов (state) // имеют эффект только в реализации фукции, а в заголовках они бесполезны. forward Func() <auto1:st1>; // warning 231: state specification on forward declaration is ignored // Однако для объявлений в старом стиле (без ключевого слова "forward") // такое предупреждение не выдавалось. Func() <auto1:st1>;- Исправлен баг, из-за которого операторы "++" и "--" не имели эффекта на результатах псевдо-инструкций "load.u.pri/alt" и "push.u" (см. #568).
- Исправлен трудноуловимый баг, из-за которого вместо перегруженного оператора "--" использовался "++".
// Оператор "++" не используется. Компилятор должен предупредить об этом (warning 203), // однако вместо этого предупреждение выводилось для оператора "--". Tag:operator ++(Tag:oper) return Tag:(_:oper + 1); // Оператор "--" используется в main(), но для него всё равно выводится warning 203. Tag:operator --(Tag:oper) // warning 203: symbol is never used: "operator--(Tag:)" return Tag:(_:oper - 1); main() { new Tag:x = Tag:0; --x--; }
Проблема заключалась в том, что из-за особенностей реализации обработчики для "++" и "--" в компиляторе были пустыми - в релизных билдах они объединялись в одну функцию (этот и многие другие методы агрессивной оптимизации - обычное дело для многих компиляторов C/C++), из-за чего компилятор Pawn вместо перегруженного оператора "++" генерировал вызов для "--" (см. комментарий к #627).
- Исправлен баг, в редких случаях приводивший к падению компилятора (см. #398).
Проблема была обнаружена ещё 2 года назад, однако её решение затрудняло то, что она проявлялась крайне редко и только в сборках для Linux и OS X.
P.S.: Всем удачных майских выходных! Особенно тем, кому тоже повезло с 10-дневными "каникулами" =)