PDA

Просмотр полной версии : [App] Pawn compiler (3.10)



Daniel_Cortez
24.05.2013, 20:12
Модифицированная версия компилятора Pawn с исправлением множества багов.

Наиболее примечательные баги, которые были исправлены:
Ошибка на строках кода длиннее 511 символов (лимит увеличен до 4095).
Падение компилятора при использовании #emit sysreq.c, если указанная функция не использовалась ранее (с некоторых пор баг снова стал проявляться, однако новый патч #157 (https://github.com/Zeex/pawn/pull/157) уже ждёт принятия).
Ошибка при использовании строк в тернарных выражениях.
Падение компилятора при использовании #emit call.
Падение компилятора из-за неправильного названия инструкции в #emit.
Условная компиляция (#if/#elseif/#else/#endif) не работала с директивой #emit.
Ошибка при передаче глобальной переменной в функцию до определения функции, из-за которой компилятор принимал переменную за неиспользуемую и удалял её из файла .amx (#131 (https://github.com/Zeex/pawn/pull/131)).



Нововведения:
Добавлен ключ командной строки "-R", использование которого включает отображение отчёта о находящихся рекурсиях в скрипте (#121 (https://github.com/Zeex/pawn/pull/121)).

Добавлена поддержка отрицательных чисел и чисел с плавающей запятой в #emit (#128 (https://github.com/Zeex/pawn/pull/128), #133 (https://github.com/Zeex/pawn/pull/133)).

Реализована возможность ограничивать видимость перечисления в пределах одного файла (удобно при создании инклудов).
Пример:

static enum eMyEnum
{
myEnumFieldA,
myEnumFieldB,
myEnumFieldC
};

Убрана автоматическая защита от повторного подключения включаемых файлов. Это было сделано из-за различий в работе такой защиты на разных ОС.
Данную защиту можно включить, активировав режим совместимости с помощью флага "-Z" или директивы #pragma compat.

Новые встроенные константы:
__line - номер текущей строки в исходном файле;
__PawnBuild - номер текущего билда компилятора;
__compat - флаг режима совместимости: 1, если включена компиляция в режиме совместимости (с ключом -Z), иначе 0;
__file - содержит строку с названием текущего исходного файла (например, "main.pwn" или "my_include.inc");
__date, __time - содержат дату и время компиляции соответственно (время запуска компилятора).



Директива #pragma compat позволяет активировать режим совместимости, в котором включена автоматическая защита от повторного подключения файлов.

Добавлена возможность показывать предупреждающие сообщения с помощью директивы #warning, по аналогии с уже существующей директивой #error, но без прерывания компиляции:
Пример:

#warning Эта строка будет выведена в отчёте компилятора

Результат:


warning 237: user warning: Эта строка будет выведена в отчёте компилятора

Также реализована многофункциональная директива #pragma warning, с помощью которой можно отключать предупреждения компилятора (#pragma warning disable <номер>), а также запоминать/восстанавливать состояние активации предупреждений (#pragma warning push/pop).
Пример:

#warning Эта строка будет выведена в отчёте компилятора

#pragma warning push // Запоминаем состояние предупреждений
#pragma warning disable 237 // Отключаем все пользовательские предупреждения (код 237)
#warning Эта строка выведена не будет
#pragma warning pop // Восстанавливаем прежнее состояние

#warning Эта строка тоже будет выведена

Результат:


warning 237: user warning: Эта строка будет выведена в отчёте компилятора
warning 237: user warning: Эта строка тоже будет выведена


Директива #pragma naked отключает предупреждения вида "function must return a value". Отличие от #pragma warning disable в том, что #pragma naked действует только в пределах одного файла.
Данная возможность может пригодиться при использовании #emit retn. Добавление return 1 в таких случаях тоже скроет предупреждение, но приведёт к генерации неиспользуемого (недостижимого) байткода.

Добавлена прогрессивная инициализация для двухмерных массивов.
Пример (взято отсюда (https://github.com/Zeex/pawn/wiki/What's-new#progressive-initializers-for-2d-arrays)):

new a[5][10] = {{0, 1, 2, ...}, {0, 2, 4, ...}, ...};

В полной записи данный массив будет выглядеть так:

new a[5][10] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18},
{0, 3, 6, 9, 12, 15, 18, 21, 24, 27},
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36},
{0, 5, 10, 15, 20, 25, 30, 35, 40, 45}
};

Также реализована возможность объявления четырёхмерных массивов (ранее был лимит в 3 измерения).
Пример:

new arr[3][1][2][3] =
{
{ { { 1, 2, 3 }, { 4, 5, 6 } } },
{ { { 7, 8, 9 }, { 10, 11, 12 } } },
{ { { 13, 14, 15 }, { 16, 17, 18 } } }
};

Добавлен новый оператор __emit.
С описанием работы данного оператора можно ознакомиться здесь: https://github.com/Zeex/pawn/pull/180#issuecomment-323531746
(Примечание (DC): В скором времени будет подготовлена русскоязычная статья по использованию оператора emit, я добавлю ссылку сюда по мере готовности.)

Ускорена компиляция больших массивов, все элементы которых инициализированы одним и тем же значением.
Теперь в ассемблерном листинге подобные массивы записываются как "dumpn <кол-во> <значение>".

Теперь при возврате массивов неизвестного размера компилятор выдаёт ошибку.
Пример:

#include <a_samp>

GetGenderName(gender_id)
{
static const gender_names[3][] = { {"male"}, {"female"}, {"undefined"} };
if (0 == gender_id)
return gender_names[0];
if (1 == gender_id)
return gender_names[1];
return gender_names[2];
}

main()
{
for (new i = 0; i < 3; ++i)
printf("#%d: %s", i, GetGenderName(i)); // error 092: functions may not return arrays of unknown size (symbol "GetGenderName")
}

Здесь компилятор выдаёт ошибку из-за того, что не знает размер последнего измерения массива gender_names. Чтобы устранить ошибку, достаточно лишь указать размер последнего измерения массива:

static const gender_names[3][10] = { {"male"}, {"female"}, {"undefined"} };


Значительно ускорена обработка исходного кода за счёт хранения глобальных идентификаторов (переменных, констант, функций) в хеш-таблице.

Добавлен параметр командной строки "-E" для интерпретации предупреждений от компилятора как ошибок.

Добавлена директива #pragma option, с помощью которой можно указывать параметры командной строки из скрипта.


Скачать: https://github.com/Zeex/pawn/releases
Исходный код на GitHub: https://github.com/pawn-lang/compiler

Источники информации: What's new (https://github.com/pawn-lang/compiler/wiki/What's-new), https://github.com/pawn-lang/compiler/wiki/Known-compiler-bugs]Known compiler bugs.
Статью подготовил: Daniel_Cortez (http://pro-pawn.ru/member.php?100-Daniel_Cortez)

Отдельная благодарность ziggi (http://pro-pawn.ru/member.php?4223) за описания некоторых ошибок и нововведений.


Специально для Pro-Pawn.ru (http://www.pro-pawn.ru)
Копирование данной статьи на других ресурсах без разрешения автора запрещено!

ziggi
04.02.2017, 10:24
v3.10.1
Build 1

Начиная с этого релиза, в версии компилятора располагается номер сборки вместо даты, то есть "1" в "3.10.1" означает "build 1". Номер сборки будет увеличиваться с каждым релизом.

Изменения относительно предыдущей версии:

Исправлена ошибка при передаче глобальной переменной в функцию до определения функции, что вызывало удаление переменной из AMX файла как неиспользуемую (#131 (https://github.com/Zeex/pawn/pull/131))
Добавлена опция -R использование которой включает отображение отчёта о находящихся рекурсиях в скрипте (#121 (https://github.com/Zeex/pawn/pull/121))
Добавлена поддержка отрицательных чисел и чисел с плавающей запятой в #emit (#128 (https://github.com/Zeex/pawn/pull/128), #133 (https://github.com/Zeex/pawn/pull/133))
Добавлена константа __PawnBuild которая содержит номер сборки текущей версии компилятора (#132 (https://github.com/Zeex/pawn/pull/132))


https://github.com/Zeex/pawn/releases

Daniel_Cortez
04.02.2017, 11:02
Ещё с прошлой недели понемногу готовлю обновление для сей статьи - сегодня-завтра собираюсь закончить, благо появилось свободное время. Не против, если использую часть твоего текста?

UPD: Буквально пару минут назад внесён коммит (https://github.com/Zeex/pawn/commit/8d6f051db4468d531c77327e2145c206bdcdb65b), добавляющий константы __file, __date и __time.

ziggi
04.02.2017, 12:59
Не против, если использую часть твоего текста?

Конечно не против.


UPD: Буквально пару минут назад внесён коммит (https://github.com/Zeex/pawn/commit/8d6f051db4468d531c77327e2145c206bdcdb65b), добавляющий константы __file, __date и __time.

О, это довольно полезно.

Daniel_Cortez
23.03.2017, 23:48
Обновил статью. Знаю, что обещал ещё месяц назад; личные обстоятельства внесли свои коррективы.
По поводу самой статьи - вполне возможно, что упустил что-нибудь, особенно на фоне того, что у меня сейчас 2 часа ночи. Дайте знать, если заметили какой-нибудь недочёт или ошибку.

DeimoS
23.03.2017, 23:58
Добавлена возможность выводить пользовательские ошибки с помощью директивы #error.
Так это же, вроде, и в "дэфолтном" компиляторе есть, не?

Alpano
24.03.2017, 00:11
recursion detected: function 40000004!=40000004 directly calls itself
recursion detected: function 40000004/0 directly calls itself
recursion detected: function 40000004*0 indirectly calls itself:
40000004*0 <- AntySH <- 40000004*0
recursion detected: function -40000004 indirectly calls itself:
-40000004 <- GetCoordBonnetVehicleEx <- -40000004
recursion detected: function AddOshive indirectly calls itself:
AddOshive <- UpdDBM <- AddOshive
...

И как понять где рекурсия?)
p.s. и ещё, функции AddOshive и UpdDBM ОБСАЛЮТНО не связаны... почему на них может ругаться?

DeimoS
24.03.2017, 01:06
Забавно...
Должно быть что-то типа такого:
http://i.imgur.com/3EQORLH.png

VVWVV
24.03.2017, 01:25
Падение компилятора при использовании #emit sysreq.c, если указанная функция не использовалась ранее.


Она до сих по не исправлена (я тестировал версию из мастер-ветки), поэтому буквально десять дней назад я отправил PR (https://github.com/Zeex/pawn/pull/157) с исправлением, который до сих пор не приняли.

ziggi
24.03.2017, 07:59
И как понять где рекурсия?)
p.s. и ещё, функции AddOshive и UpdDBM ОБСАЛЮТНО не связаны... почему на них может ругаться?

Покажи код.

Daniel_Cortez
24.03.2017, 17:28
Так это же, вроде, и в "дэфолтном" компиляторе есть, не?
Да, действительно, в стоковом есть директива #assert. Я добавил в статью небольшое замечание об отличии #assert от #error.



Она до сих по не исправлена (я тестировал версию из мастер-ветки), поэтому буквально десять дней назад я отправил PR (https://github.com/Zeex/pawn/pull/157) с исправлением, который до сих пор не приняли.
Странно, я почему-то думал, что его приняли - спутал с каким-то другим, видимо. Добавил примечание в статье.

DeimoS
24.03.2017, 17:50
Да, действительно, в стоковом есть директива #assert. Я добавил в статью небольшое замечание об отличии #assert от #error.

Не, там именно директива "#error" присутствует
http://i.imgur.com/boSnOTX.png

Alpano
24.03.2017, 17:53
Покажи код.

stock AddOshive(playerid,ochiveid){
if(Ochives[playerid][ochiveid]) return false;
new points = GetOchivePoints(ochiveid),
string[128],year, month, day;
Player[playerid][OchivePoints] += points;
GivePlayerCash(playerid,points*10000);
Ochives[playerid][ochiveid] = true;
Ochive[playerid]++;
getdate(year, month, day);
format(string, sizeof(string),"INSERT INTO `Ochives` VALUES ( NULL,'%d','%d','%02d.%02d.%d')",Player[playerid][pSQLID],ochiveid,day,month,year);
db_free_result(db_query(users_base,string));
SavePlayerInt(playerid,"OchivePoints",Player[playerid][OchivePoints]);
if(!(playerFlags[playerid] & pMooveMode))
GameTextForPlayer(playerid, "~w~New achieve!", 3000, 1);
return true;
}


stock UpdDBM(){
stateDBM--;
if(stateDBM < 0){
stateDBM = 480+INTERVAL_DMB;
prizeDBM = 50000;
}
if(stateDBM < 300+INTERVAL_DMB)
return true;
else if(stateDBM > 420+INTERVAL_DMB){
new msg[64];
format(msg,sizeof(msg),"~n~~n~~n~~n~~n~~n~~n~~n~~n~~w~Wait %d sec.",stateDBM-(420+INTERVAL_DMB));
foreach(i){
if(!IsPlayerInDynamicArea(i, areaDBM)) continue;
GameTextForPlayer(i,msg,1250,3);
}
}else if(stateDBM == 420+INTERVAL_DMB){
for(new i; i < 8; i++)
SetVehicleParamsEx(dbmPOS[i][IDo],1,(hour < 7 || hour > 21)?1:0,0,0,0,0,0);
new playersindt;
foreach(i){
if(!IsPlayerInDynamicArea(i, areaDBM)) continue;
SetCameraBehindPlayer(i);
TogglePlayerControllable(i, true);
GameTextForPlayer(i,"~r~GO!",1500,6);
playersindt++;
}
if(playersindt < 2){
if(playersindt){
foreach(i){
if(!IsPlayerInDynamicArea(i, areaDBM)) continue;
GivePlayerCash(i,50000);
break;
}
DellAllFromDBM();
}
stateDBM = 300+INTERVAL_DMB;
return true;
}
}else if(stateDBM == 390+INTERVAL_DMB || stateDBM == 360+INTERVAL_DMB || stateDBM == 330+INTERVAL_DMB){
UpdateDBM();
foreach(i){
if(!IsPlayerInDynamicArea(i, areaDBM)) continue;
GameTextForPlayer(i,"~r~LIFT DOWN!",1500,6);
}
}else if(stateDBM == 300+INTERVAL_DMB){
foreach(i){
if(!IsPlayerInDynamicArea(i, areaDBM)) continue;
GameTextForPlayer(i,"~g~Winner!",1000,6);
GivePlayerCash(i,prizeDBM/3);
GivePlayerScore(i,GetPrizeRaceExp(Player[i][pLevel]));
AddOshive(i,WIN_DERBY);
AddPlayerHistory(i,2,1);
}
DellAllFromDBM();
st_etaj[0] = false;
st_etaj[1] = false;
st_etaj[2] = false;
for(new f; f < sizeof(etaj_tre); f++)
MoveDynamicObject(etaj_tre[f][IDo],etaj_tre[f][pPosX], etaj_tre[f][pPosY],2.9,0.3);
for(new f; f < sizeof(etaj_two); f++)
MoveDynamicObject(etaj_two[f][IDo],etaj_two[f][pPosX], etaj_two[f][pPosY],2.9,0.3);
MoveDynamicObject(etaj_one[1][IDo],etaj_one[1][pPosX], etaj_one[1][pPosY],2.9,0.3);
MoveDynamicObject(etaj_one[2][IDo],etaj_one[2][pPosX], etaj_one[2][pPosY],2.9,0.3);
}
return true;
}

Да, во втором есть AddOshive, но обратной связи нет обсалютно.

VVWVV
01.08.2017, 23:54
Странно, я почему-то думал, что его приняли - спутал с каким-то другим, видимо. Добавил примечание в статье.
Следует обновить статью, поскольку фикс был принят.

Кроме того, теперь можно обновить библиотеки, в которых есть обход данной ошибки, чтобы не генерировать бесполезный байт-код.


Условная компиляция (#if/#elif/#else/#endif) не работала с директивой #emit.
Скорее всего это опечатка, ведь в Pawn нет препроцессорной директивы '#elif', ибо вместо неё есть '#elseif'.


__file - содержит строку с названием текущего исходного файла (например, "main.pwn" или "my_include.inc");
Следует заметить, что в инклюдах генерируется полный путь к файлу, а в исходных файлах только лишь название этого файла.

Daniel_Cortez
02.08.2017, 20:17
Следует обновить статью, поскольку фикс был принят.

Кроме того, теперь можно обновить библиотеки, в которых есть обход данной ошибки, чтобы не генерировать бесполезный байт-код.
Можно было бы определить наличие фикса по значению в константе __PawnBuild, но его так и не повысили.



Скорее всего это опечатка, ведь в Pawn нет препроцессорной директивы '#elif', ибо вместо неё есть '#elseif'.
Да, действительно. Исправил.



Следует заметить, что в инклюдах генерируется полный путь к файлу, а в исходных файлах только лишь название этого файла.
Не совсем. Допустим, что сервер находится в папке "C:\MyServer". Для исходного файла выдаётся полное имя.
Пример:

C:\MyServer\gamemodes\main.pwn
Для инклуда, подключенного с указанием относительного пути, выдаёт относительный путь:

#include "../include/test.inc"

../include/test.inc
Для остальных способов подключения в __file тоже полное имя:


#include <test>
#include "test.inc"
#include <test.inc>
#include "test"
#include test


C:\MyServer\pawno\include\test.inc

123
29.08.2017, 17:51
Похоже, компилятор не правильно компилирует конструкцию вида -


if(clickedid == TD_join[3])
if(--model_number < 0) model_number = 7;
else if(clickedid == TD_join[4])
if(++model_number >= 8) model_number = 0;

Выдаёт:

warning 217: loose indentation

Однако, если скомпилировать вот так:


if(clickedid == TD_join[3]) if(--model_number < 0) model_number = 7;
else if(clickedid == TD_join[4]) if(++model_number >= 8) model_number = 0;

Ошибка пропадает, однако вторая часть конструкции:

else if(clickedid == TD_join[4]) if(++model_number >= 8) model_number = 0;

Работает некорректно (точнее вовсе не работает).

Версия последняя:

Pawn compiler 3.10.2 Copyright (c) 1997-2006, ITB CompuPhase

Если кто пользуется данным компилятором, проверьте проблему.

Daniel_Cortez
30.08.2017, 04:20
Похоже, компилятор не правильно компилирует конструкцию вида -


if(clickedid == TD_join[3])
if(--model_number < 0) model_number = 7;
else if(clickedid == TD_join[4])
if(++model_number >= 8) model_number = 0;

Компилятор всё делает правильно. Оператор else относится к последнему встреченному if, а не к первому.
Если сделать правильное выравнивание, код будет выглядеть так:


if(clickedid == TD_join[3])
if(--model_number < 0) model_number = 7;
else if(clickedid == TD_join[4])
if(++model_number >= 8) model_number = 0;

Или даже так:


if(clickedid == TD_join[3])
if(--model_number < 0) model_number = 7;
else
if(clickedid == TD_join[4])
if(++model_number >= 8) model_number = 0;

Если же вы хотите, чтобы код в else относился к первому if, выделяйте тело ветвления фигурными скобками:


if(clickedid == TD_join[3])
{
if(--model_number < 0) model_number = 7;
}
else if(clickedid == TD_join[4])
{
if(++model_number >= 8) model_number = 0;
}


UPD: Насколько помню, такая задача в стиле "Найди ошибку" даже есть в ЕГЭ по информатике. Или, по крайней мере, была там 5 лет тому назад.

DeimoS
31.08.2017, 15:59
UPD: Насколько помню, такая задача в стиле "Найди ошибку" даже есть в ЕГЭ по информатике. Или, по крайней мере, была там 5 лет тому назад.

И правильным ответом было "В коде всё верно! Это компилятор всё делает неправильно!!!"?

Daniel_Cortez
31.08.2017, 17:32
И правильным ответом было "В коде всё верно! Это компилятор всё делает неправильно!!!"?
Ок, возможно, я не совсем удачно всё это сформулировал. В ветках if/else было присваивание переменной разных значений и нужно было определить, какое значение в конце концов окажется в переменной. Но основная суть всё та же: неправильная табуляция могла сбить с толку.

DeimoS
31.08.2017, 18:04
Ок, возможно, я не совсем удачно всё это сформулировал. В ветках if/else было присваивание переменной разных значений и нужно было определить, какое значение в конце концов окажется в переменной. Но основная суть всё та же: неправильная табуляция могла сбить с толку.

Да не, ты всё правильно сформулировал. Это я просто решил немного устроить оффтоп и пошутить :pardon:

Daniel_Cortez
24.10.2017, 20:05
Вышел новый релиз 3.10.3.

Изменения:
Добавлен новый оператор emit/__emit.
С описанием работы данного оператора можно ознакомиться здесь (https://github.com/Zeex/pawn/pull/180#issuecomment-323531746).
(Примечание (DC): В скором времени будет подготовлена русскоязычная статья по использованию оператора emit, я добавлю ссылку сюда по мере готовности.)


Ускорена компиляция больших массивов, все элементы которых инициализированы одним и тем же значением.
Теперь в ассемблерном листинге подобные массивы записываются как "dumpn <кол-во> <значение>".


Теперь при возврате массивов неизвестного размера компилятор выдаёт ошибку.
Пример:



#include <a_samp>

GetGenderName(gender_id)
{
static const gender_names[3][] = { {"male"}, {"female"}, {"undefined"} };
if (0 == gender_id)
return gender_names[0];
if (1 == gender_id)
return gender_names[1];
return gender_names[2];
}

main()
{
for (new i = 0; i < 3; ++i)
printf("#%d: %s", i, GetGenderName(i)); // error 092: functions may not return arrays of unknown size (symbol "GetGenderName")
}


Здесь компилятор выдаёт ошибку из-за того, что не знает размер последнего измерения массива gender_names. Чтобы устранить ошибку, достаточно лишь указать размер последнего измерения массива:


static const gender_names[3][10] = { {"male"}, {"female"}, {"undefined"} };



Устранён баг с ложным предупреждением о присвоении переменной значения из самой себя.
Данный баг возникал при использовании операторов "-" (в унарном варианте), "!" и "~".


enum e_Data{
val1, val2, val3
};
new data[e_Info];

// warning 226: a variable is assigned to itself (symbol "data")
data[val1] = -data[val1];
data[val2] = ~data[val2];
data[val3] = !data[val3];



Исправлены ошибки, связанные с инициализацией многомерных массивов.


Устранён краш при использовании #emit sysreq.c на не использовавшихся ранее в коде нативных функциях.
(Примечание (DC): Да, опять.)


Исправлена ошибка, из-за которой в документацию (*.xml) для автоматонов вместо имён состояний попадали мусорные данные (https://github.com/Zeex/pawn/issues/184).


Устранён баг, из-за которого константы, указанные в аргументах командной строки, не имели никакого эффекта.


Устранён баг, связанный с поааданием лишних пустых строк и символов '\a' в листинг препроцессора при использовании директив #pragma deprecated и #warning.


Устранено попадание лишних пустых строк в ассемблерный листинг.


Исправлены ошибки, возникавшие при сборке для ОС Android.


Скачать: https://github.com/Zeex/pawn/releases/tag/v3.10.3

Параллельно подготовлен тестовый выпуск, в котором, помимо всего вышеперечисленного, внесён ряд изменений для улучшения производительности.
(Примечение (DC): Особенно заметно уменьшение времени компиляции на крупных модах. Например, при компиляции мода Open-GTO (https://github.com/Open-GTO/Open-GTO) на моём ПК время сборки уменьшилось с 18 до 6 секунд.)
https://github.com/Zeex/pawn/releases/tag/v3.10.3-performance

ziggi
25.10.2017, 09:49
Супер релиз, спасибо за участие в оптимизации скорости.

Daniel_Cortez
25.10.2017, 12:46
Супер релиз, спасибо за участие в оптимизации скорости.
Да я там почти ничего не сделал, разве что немного подправил код maddinat0r'а и оптимизировал использование константы __line (последнее изначально реализовал justnonamenoname (https://github.com/justnonamenoname)).
Другое дело вот этот (https://github.com/Zeex/pawn/pull/201) патч для ещё более эффективной записи массивов с одинаковыми значениями (при сборке Open-GTO время компиляции слегка уменьшилось - с 16 до 14,5 секунд на моей машине), но я сомневаюсь, что его примут на фоне того, что сделал maddinat0r.

DeimoS
25.10.2017, 17:37
Мод, который компилировался за минуту с лишним, стал компилироваться за 7 секунд. Что вы там сделали такого?

VVWVV
25.10.2017, 17:50
Мод, который компилировался за минуту с лишним, стал компилироваться за 7 секунд. Что вы там сделали такого?

1) Хеш-таблицы.
2) Немного других изменений.

Вроде бы все.

Daniel_Cortez
25.10.2017, 18:51
Мод, который компилировался за минуту с лишним, стал компилироваться за 7 секунд. Что вы там сделали такого?
Львиная доля повышения производительности приходится на хранение всех глобальных идентификаторов (глобальных переменных, констант, функций) в хеш-таблице, благодаря чему для поиска того или иного идентификатора по имени не нужно просматривать весь список глобальных идентификаторов, как раньше.
Правда, цена этому - использование 128 Мб оперативы, потому что maddinat0r зачем-то посчитал нужным резервировать в хеш-таблице целых 8 миллионов слотов (хотя на самом деле их там резервируется 16 млн.), в то время как даже для самых крупных модов может хватить до 16 тысяч слотов (например, для того же Open-GTO хватило всего 4 тысяч), а даже если не хватит, таблица сама может автоматически увеличить свой размер.
Ещё немного скорость увеличилась за счёт того, что компилятор больше не выискивает встроенную константу __line в таблицах сначала локальных, а затем и глобальных идентификаторов каждый раз, когда нужно изменить её значение (а оно должно изменяться с каждой новой строкой кода). Изначально это было сделано ещё в форке justnonamenoname (https://github.com/justnonamenoname) (также известном как "the fast russian compiler").

На самом деле, можно выжать ещё немного скорости. Не сделай maddinat0r свой Pull Request так рано, я мог бы попробовать портировать ещё пару-тройку оптимизаций из форка justnonamenoname, но теперь их уже вряд ли примут по отдельности.

ziggi
25.10.2017, 20:56
Львиная доля повышения производительности приходится на хранение всех глобальных идентификаторов (глобальных переменных, констант, функций) в хеш-таблице, благодаря чему для поиска того или иного идентификатора по имени не нужно просматривать весь список глобальных идентификаторов, как раньше.
Правда, цена этому - использование 128 Мб оперативы, потому что maddinat0r зачем-то посчитал нужным резервировать в хеш-таблице целых 8 миллионов слотов (хотя на самом деле их там резервируется 16 млн.), в то время как даже для самых крупных модов может хватить до 16 тысяч слотов (например, для того же Open-GTO хватило всего 4 тысяч), а даже если не хватит, таблица сама может автоматически увеличить свой размер.
Ещё немного скорость увеличилась за счёт того, что компилятор больше не выискивает встроенную константу __line в таблицах сначала локальных, а затем и глобальных идентификаторов каждый раз, когда нужно изменить её значение (а оно должно изменяться с каждой новой строкой кода). Изначально это было сделано ещё в форке justnonamenoname (https://github.com/justnonamenoname) (также известном как "the fast russian compiler").

На самом деле, можно выжать ещё немного скорости. Не сделай maddinat0r свой Pull Request так рано, я мог бы попробовать портировать ещё пару-тройку оптимизаций из форка justnonamenoname, но теперь их уже вряд ли примут по отдельности.

Другие оптимизации можно же после слияния этого PR добавить.

Для интереса попросил Eakwarp'а протестировать со своим Valakas. На сколько мне известно, размеры его amx уходят за 100 Мб.

DeimoS
26.10.2017, 17:12
Нашёл баг в тестовой версии. При "скреплении" строк через "\" все пробелы между двумя строками исчезают.
То бишь:

print("test \
test");
После компиляции пробелы перед "\" исчезнут и в консоль выдаст "testtest", а не "test test".

Daniel_Cortez
26.10.2017, 17:24
Нашёл баг в тестовой версии. При "скреплении" строк через "\" все пробелы между двумя строками исчезают.
То бишь:

print("test \
test");
После компиляции пробелы перед "\" исчезнут и в консоль выдаст "testtest", а не "test test".
Об этом баге уже сообщили (https://github.com/Zeex/pawn/pull/199#issuecomment-339477846). Остаётся надеяться, что исправят быстро и не придётся опять полгода ждать нового релиза.

vasyok28
26.10.2017, 18:57
Ничего себе, реально быстро компилит, раньше компилировал за 1:52 сек щас за 14 сек. :dirol::drinks:

ziggi
26.10.2017, 19:22
Для интереса попросил Eakwarp'а протестировать со своим Valakas. На сколько мне известно, размеры его amx уходят за 100 Мб.

Результаты:

3.10.2 - с итоговым AMX в 90358кб - 5 минут 30 секунд
3.10.3 - 28 секунд

Fallen A.
26.10.2017, 19:48
Результаты:

Мой amx весит 2мб, к примеру.

В целом, на версии 3.10.2 скорость компиляции была около 4-7 секунд.
На версии 3.10.3 3-6 сек.

Daniel_Cortez
31.10.2017, 00:07
За последние несколько дней уже успели исправить проблему с исчезающими при переносе строк пробелами, и приняли патч, в несколько раз ускоряющий процесс сборки многих крупных модов. Тем не менее, до релиза может пройти ещё неизвестно сколько времени, поэтому я подготовил "неофициальный" релиз.

Наиболее значительные изменения:
Серия изменений для улучшения производительности компилятора (1 (https://github.com/Zeex/pawn/pull/199), 2 (https://github.com/Zeex/pawn/pull/201)).

Исправлена необоснованная аллокация 128 Мб памяти под хеш-таблицу.
128 Кб (16384 слотов) вполне должно хватить даже для самых крупных модов.

Устранён баг с исчезновением пробелов в строках.

Исправлена сборка под Visual Studio 2010 (==> меньше жалоб от тех, у кого не установлены библиотеки VC++ Runtime старше 2010-й версии).


Скачать: Dropbox (https://www.dropbox.com/s/yyip7itkxarhnac/pawnc-3.10.3-exp.zip?dl=0), RGHost (http://rgho.st/7Q4PFYTY6), Яндекс.Диск (https://yadi.sk/d/Ea0QMuvq3PNXKV)
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/experimental

Дисклеймер: Я не несу ответственности за возможный ущерб в следствие использования (в том числе неправильного использования) данного билда. Используйте на свой страх и риск. Как уже было отмечено выше, этот релиз неофициальный.

DeimoS
31.10.2017, 00:35
Исправлена необоснованная аллокация 128 Мб памяти под хеш-таблицу.
128 Кб (16384 слотов) вполне должно хватить даже для самых крупных модов.

Как я понимаю, нельзя сделать эту настройку опциональной?

Daniel_Cortez
31.10.2017, 11:54
Как я понимаю, нельзя сделать эту настройку опциональной?
На самом деле, я хотел создать issue с подобным предложением на GitHub. Но, учитывая опыт с моим предыдущим комментарием (https://github.com/Zeex/pawn/pull/199#issuecomment-338476750) о размере хеш-таблицы (спойлер: его никто не прочёл, PR приняли без единого нарекания), я более чем уверен: это бесполезно.

Да и вообще, не думаю, что найдётся хоть один мод, который сможет превысить лимит в 16384 глобальных идентификатора.
Я пробовал скомпилировать несколько модов с патчем (https://github.com/Daniel-Cortez/pawn-3.10/commit/13203dcb7d1d33f6ace9456e095f0348e2d1cfa0), позволяющим подсчитать максимально использованное количество слотов в хеш-таблице. Наибольший результат показал Open-GTO - 4120 слотов, остальные использовали не более 2 с небольшим тысяч. Даже тот же пресловутый RLS образца 2011 года заставил компилятор использовать только 1914 слотов.
Чтобы превысить изначальный размер в 16k слотов, нужен просто титанический, невиданных доселе размеров мод. Но даже если такой и существует, ничего страшного не произойдёт: хеш-таблица просто вырастет в 2 раза, до 32768 слотов.

Blood
01.11.2017, 00:38
Daniel_Cortez можешь залит на другой ФО ?

Daniel_Cortez
01.11.2017, 12:52
Daniel_Cortez можешь залит на другой ФО ?
Чем не устраивает dropbox? Регистрацией перед скачиванием? От неё можно отказаться, если быть хоть немного внимательным.

DeimoS
01.11.2017, 15:34
Чем не устраивает dropbox? Регистрацией перед скачиванием? От неё можно отказаться, если быть хоть немного внимательным.

Он довольно топорно работает иногда. У меня вообще минуты по 4 загружает сайт.

whale
01.11.2017, 16:23
DC, спасибо за релиз. Скорость компиляции заметно повысилась.

// ~1.1-1.4s => ~0.4-0.6s

Blood
01.11.2017, 20:29
Чем не устраивает dropbox? Регистрацией перед скачиванием? От неё можно отказаться, если быть хоть немного внимательным.

При скачивание выдает ошибку .

Daniel_Cortez
02.11.2017, 12:36
Он довольно топорно работает иногда. У меня вообще минуты по 4 загружает сайт.
Странно, я думал, это только у меня подобные странности с Dropbox (в Firefox не грузится форма загрузки файлов, приходится отдельно Chromium открывать).



При скачивание выдает ошибку .
"... но какая именно ошибка, не скажу."


Ок, вы победили. Добавил в пост с релизом ссылку (http://rgho.st/7Q4PFYTY6) на скачивание с RGhost. Если есть предложения получше, буду рад выслушать.

Blood
02.11.2017, 13:34
"... но какая именно ошибка, не скажу."


При скачивании файла произошла ошибка.

ziggi
02.11.2017, 14:11
Странно, я думал, это только у меня подобные странности с Dropbox (в Firefox не грузится форма загрузки файлов, приходится отдельно Chromium открывать).



"... но какая именно ошибка, не скажу."


Ок, вы победили. Добавил в пост с релизом ссылку (http://rgho.st/7Q4PFYTY6) на скачивание с RGHost. Если есть предложения получше, буду рад выслушать.

Яндекс.Диск, MEGA

Daniel_Cortez
03.11.2017, 13:18
Яндекс.Диск, MEGA
Сделал (https://yadi.sk/d/Ea0QMuvq3PNXKV).

Также для удобства тех, кто только начал читать эту тему, ссылка на пост с релизом: http://pro-pawn.ru/showthread.php?2207&p=88008&viewfull=1#post88008

geneff
04.11.2017, 02:54
Подскажите мне тупому, почему у меня компиляция не ускорилась? -_-

DeimoS
04.11.2017, 14:22
Потому что в коде минимум глобальных массивов и всего того, что было оптимизированно?
Либо же не туда распаковал файлы/не тем компилятором компилируешь

geneff
04.11.2017, 17:37
Так-с, нужно было скачать этот архив (https://yadi.sk/d/Ea0QMuvq3PNXKV) , файлы из архива перекинуть в папку "pawno", открыть "pawno.exe", открыть исходный код мода и нажать F5, так?

Daniel_Cortez
05.11.2017, 17:19
Релиз 3.10.4.
Значительно повышена скорость компиляции.
Добавлен параметр командной строки "-E" для интерпретации предупреждений от компилятора как ошибок.
Добавлена директива #pragma option, с помощью которой можно указывать параметры командной строки из скрипта.
Исправлен баг с переносом строк, из-за которого из строк в месте переноса исчезали пробелы.


Скачать: https://github.com/Zeex/pawn/releases/tag/v3.10.4

vovandolg
06.11.2017, 03:42
Странно, я думал, это только у меня подобные странности с Dropbox (в Firefox не грузится форма загрузки файлов, приходится отдельно Chromium открывать).

с приложения(андроида) заливаю туда файлы, вродь норм всё...

Salik_Davince
09.11.2017, 20:39
Да быстрее компилирует, но все таки не быстрее компилятора (я так думаю) от Серёги Заводина.

UPD: Почти тоже самое.

ziggi
01.12.2017, 13:45
Хотел узнать, реально ли оптимизировать конструкцию switch/case, а именно диапазоны значений?

Daniel_Cortez
01.12.2017, 14:34
Хотел узнать, реально ли оптимизировать конструкцию switch/case, а именно диапазоны значений?
Если вопрос адресован мне, то не совсем понимаю, о чём ты.
В switch/case диапазон значений - это просто синтаксический сахар, на самом же деле для каждого значения из диапазона генерируется отдельная пара <значение>:<адрес перехода>. Если же нужно сравнение с одним непрерывным диапазоном значений, во многих случаях выгоднее будет использовать if со сравнением входного значения с крайними элементами диапазона. Эту оптимизацию ты имел в виду?

ziggi
01.12.2017, 15:36
Если вопрос адресован мне, то не совсем понимаю, о чём ты.
В switch/case диапазон значений - это просто синтаксический сахар, на самом же деле для каждого значения из диапазона генерируется отдельная пара <значение>:<адрес перехода>. Если же нужно сравнение с одним непрерывным диапазоном значений, во многих случаях выгоднее будет использовать if со сравнением входного значения с крайними элементами диапазона. Эту оптимизацию ты имел в виду?

Да, именно оптимизацию вот этой генерации я и имею ввиду. То есть, чтобы на уровне компиляции, при использовании switch/case, генерировались инструкции, как при использовании if.

Daniel_Cortez
01.12.2017, 19:10
Да, именно оптимизацию вот этой генерации я и имею ввиду. То есть, чтобы на уровне компиляции, при использовании switch/case, генерировались инструкции, как при использовании if.
Обычно компилятор анализирует код и генерирует ассемблерный листинг "на лету", т.е. полную информацию обо всех значениях для таблицы переходов (case) он будет знать только когда найдёт закрывающую фигурную скобку от switch - к тому моменту он уже сгенерирует инструкции AMX для всего кода внутри switch и только после этих инструкций оставит таблицу переходов. В принципе перед записью таблицы можно сделать анализ всех её значений и на основе принятого решения либо записать эту таблицу в обычном порядке, либо вместо неё вывести в листинг инструкции сравнения с крайними значениями диапазона и перехода, как для оператора if, заодно заменив инструкцию 'switch' (она генерируется перед содержимым конструкции switch) на 'jump' (операнд оставить прежним).

Это самая простая реализация, которую у меня получилось придумать, но даже после этого я очень сомневаюсь, что что-то подобное примут, по одной простой причине:
https://github.com/Zeex/pawn/issues/112
В сообществе SA-MP грязные хаки типа сканирования кода - достаточное основание, чтобы отказаться от тех или иных оптимизаций. Sad but true.

Daniel_Cortez
31.12.2017, 15:10
Вышла новая версия 3.10.5.

Изменения с прошлой версии:
Ещё больше ускорена компиляция однородных массивов (#201 (https://github.com/Zeex/pawn/pull/201)).
Добавлен оператор конкатенации "##" (#205 (https://github.com/Zeex/pawn/pull/205)).
Улучшена реализация оператора "emit" (#211 (https://github.com/Zeex/pawn/pull/211)).
В новой версии исправлено несколько багов и недочётов, а также значительно переработан синтаксис оператора.
Подробнее о новом синтаксисе и преимуществах перед директивой #emit можно прочесть здесь: http://pro-pawn.ru/showthread.php?15830.
Теперь компилятор выдаёт ошибку при повторном объявлении одной и той же метки (#215 (https://github.com/Zeex/pawn/pull/215)).


Тем не менее, оператор конкатенации оказался недоработанным (issue #224 (https://github.com/Zeex/pawn/issues/224)), из-за чего компилятор неправильно работает с псевдо-оператором "extract" из инклуда sscanf2.inc, инклудами из YSI и прочим кодом, в котором в макросах используется сочетание "##".
Как результат, новый релиз компилятора не работает со многими модами.

Для временного исправления проблемы я подготовил свой "неофициальный" релиз.
Отличия от стандартного релиза 3.10.5:
Удалён оператор конкатенации "##", из-за которого компилятор работал неправильно.
Исправлено необоснованное использование 128 Мб ОЗУ под хеш-таблицу для глобальных символов, кол-во слотов снижено с 16'777'216 до 16384.
В ближайшее время я попробую открыть issue с обсуждением размера хеш-таблицы, но пока что оставлю эту временную меру для неофициального билда.
Применён патч для сборки с помощью Visual Studio 2010 (runtime-библиотеки VC++ 2010 более распространены, чем из 2012-го выпуска ==> меньше проблем с запуском компилятора).


Скачать: RGhost (http://rgho.st/6Q4PvKBn6), Dropbox (https://www.dropbox.com/s/flqodgkg6lir2fg/pawnc-3.10.5-exp.7z?dl=0).
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/experimental

VVWVV
31.12.2017, 20:39
Следует отметить, что оператор конкатенации работал бы правильно, если бы правильно работал оператор #.
P.s. как PR вообще приняли?!

Daniel_Cortez
31.12.2017, 22:24
Следует отметить, что оператор конкатенации работал бы правильно, если бы правильно работал оператор #.
P.s. как PR вообще приняли?!
Точно так же, как и расточительство с 128 Мб ОЗУ под хеш-таблицу, наверное. У Zeex'а просто нет ни времени, ни мотивации возиться с новыми issue/PR. Собственно, он сам это признал, оставив сообщение (https://github.com/Zeex/pawn/commit/c469ec2ec1159e57aa09ba4b3745f483b7c69b53) о том, что больше не собирается продолжать работу над компилятором. Остаётся надеяться, что найдётся кто-нибудь, кто сможет взять на себя лидерство над проектом.

И да, за сегодня успела выйти ещё одна новая версия, 3.10.6, в которой уже нет оператора конкатенации, вызывавшего проблемы со многими модами, однако на странице релиза (https://github.com/Zeex/pawn/releases/tag/v3.10.6) ссылок на бинарники нет, только исходники. По сути он ничем не отличается от моего билда в посте выше, разве что зависит он от рантайма VC++ менее распространённого 2012-го выпуска и не исправлен недочёт с расходом 128 Мб ОЗУ, поэтому я рекомендую всё же пользоваться неофициальным билдом.

123
01.01.2018, 06:20
Точно так же, как и расточительство с 128 Мб ОЗУ под хеш-таблицу, наверное. У Zeex'а просто нет ни времени, ни мотивации возиться с новыми issue/PR. Собственно, он сам это признал, оставив сообщение (https://github.com/Zeex/pawn/commit/c469ec2ec1159e57aa09ba4b3745f483b7c69b53) о том, что больше не собирается продолжать работу над компилятором. Остаётся надеяться, что найдётся кто-нибудь, кто сможет взять на себя лидерство над проектом.

И да, за сегодня успела выйти ещё одна новая версия, 3.10.6, в которой уже нет оператора конкатенации, вызывавшего проблемы со многими модами, однако на странице релиза (https://github.com/Zeex/pawn/releases/tag/v3.10.6) ссылок на бинарники нет, только исходники. По сути он ничем не отличается от моего билда в посте выше, разве что зависит он от рантайма VC++ менее распространённого 2012-го выпуска и не исправлен недочёт с расходом 128 Мб ОЗУ, поэтому я рекомендую всё же пользоваться неофициальным билдом.

А что мешает взять Вам лидерство над проектом, и продолжить его развитие? Более лучшей кандидатуры не найти, к тому же, вы вложили не малый вклад, что позволило выйти в свет новым версиям. Если судить по сообщениям, Вам небезразлична судьба проекта.

Daniel_Cortez
02.01.2018, 16:08
А что мешает взять Вам лидерство над проектом, и продолжить его развитие?
Неумение работать с сервисами продолжительной интеграции (Travis CI, AppVeyor), плохое представление о "внутренностях" компилятора (едва удалось недавно переделать оператор emit и (надеюсь) исправить в нём все баги), да и знание английского далеко не на высоте (могу делать переводы статей для форума, но на составление текстов на инглише всё ещё уходит много времени).


Более лучшей кандидатуры не найти
Не знаю, с чего вы это решили, но более подходящих кандидатов в сообществе ещё много. Например, сейчас репозиторий передан к Southclaws (https://github.com/Southclaws/pawn).


Если судить по сообщениям, Вам небезразлична судьба проекта.
Да, но только потому что на нём базируется мой собственный форк Pawn, нацеленный на упрощение задачи по встраиванию интерпретатора в пользовательские приложения, а также устранение багов и уязвимостей в оном.
Я уже давно ничего не делаю в SA-MP, а потому и компилятором конкретно из репозитория Zeex'а не пользуюсь (вместо него юзаю тот, который в моём репо, хоть он и основывается на первом). Собственно, на том же своём форке и тестировал все патчи, которые потом пересылал в репо Zeex'а, ибо не было смысла держать их только у себя.

Unreal
04.01.2018, 14:00
Обновил до 3.10.6 и после у меня появляется это при компиляций:



Header size: 19392 bytes
Code size: 3012404 bytes
Data size: 2701860 bytes
Stack/heap size: 4492 bytes; estimated max. usage=1090 cells (4360 bytes)
Total requirements: 5738148 bytes


это дебаг или что? до этого использовал стандартный 3.2

Daniel_Cortez
04.01.2018, 14:20
Обновил до 3.10.6 и после у меня появляется это при компиляций:



Header size: 19392 bytes
Code size: 3012404 bytes
Data size: 2701860 bytes
Stack/heap size: 4492 bytes; estimated max. usage=1090 cells (4360 bytes)
Total requirements: 5738148 bytes


это дебаг или что? до этого использовал стандартный 3.2
С какими параметрами запускаете компилятор? Перечислите все ключи, которые есть в pawn.cfg (а также в settings.ini, если вы нехороший человек и пользуетесь Pawno).

ziggi
04.01.2018, 17:44
Обновил до 3.10.6 и после у меня появляется это при компиляций:



Header size: 19392 bytes
Code size: 3012404 bytes
Data size: 2701860 bytes
Stack/heap size: 4492 bytes; estimated max. usage=1090 cells (4360 bytes)
Total requirements: 5738148 bytes


это дебаг или что? до этого использовал стандартный 3.2

Зачем уменьшать размер стека?)

Daniel_Cortez
31.01.2018, 18:57
Проект переведён на аккаунт группы pawn-lang (https://github.com/pawn-lang), которой на данный момент управляют 3 человека: Zeex (https://github.com/Zeex), Y_Less (https://github.com/Y-Less) и YashasSamaga (https://github.com/YashasSamaga). Также, судя по одному из проектов (https://github.com/pawn-lang/pawn-lang.github.io) в группе, в скором времени возможно введение в строй сайта pawn-lang.org (http://pawn-lang.org).

Fallen A.
23.02.2018, 15:33
Перешел с 3.10.3 на версию от кортеза 3.10.5.

Компиляция было: 8.1 сек.
Компиляция стало: 1.6 сек.

Честно признаться, я в шоке :)

Daniel_Cortez
24.02.2018, 02:23
Перешел с 3.10.3 на версию от кортеза 3.10.5.

Компиляция было: 8.1 сек.
Компиляция стало: 1.6 сек.

Честно признаться, я в шоке :)
Это ещё не предел, на подходе PR #255 (https://github.com/pawn-lang/compiler/pull/255) - ускорение компиляции массивов с неоднородными начальными значениями. Лучше всего эффект заметен на больших массивах. Как уже написано в комментарии к тому PR, для инклуда modelsizes.inc (https://github.com/Crayder/Model-Sizes-Plus) время компиляции удалось уменьшить с 13.7 до 0.95 секунд.

Fallen A.
24.02.2018, 13:58
Это ещё не предел, на подходе PR #255 (https://github.com/pawn-lang/compiler/pull/255) - ускорение компиляции массивов с неоднородными начальными значениями. Лучше всего эффект заметен на больших массивах. Как уже написано в комментарии к тому PR, для инклуда modelsizes.inc (https://github.com/Crayder/Model-Sizes-Plus) время компиляции удалось уменьшить с 13.7 до 0.95 секунд.

У меня ощущение, что тебя скоро заблокируют за количество созданных тобой PR.

Daniel_Cortez
24.04.2018, 19:58
Вышла новая версия 3.10.7.

Скачать: https://github.com/Zeex/pawn/releases/tag/v3.10.7

Изменения:
Нововведения и багфиксы для оператора emit (#279 (https://github.com/pawn-lang/compiler/pull/279)).

В варнинг о неиспользуемом идентификаторе добавлена информация о том, где идентификатор объявлен (#252 (https://github.com/pawn-lang/compiler/pull/252)).
Раньше варнинг отображался на самой последней строке в скрипте, из-за чего приходилось самостоятельно искать место объявления переменной.
Пример:

#include <a_samp>

new g_var; // test.pwn(3) : warning 203: symbol is never used: "g_var"

main(){}

Добавлено больше информации в варнинг о несовпадении тегов (#265 (https://github.com/pawn-lang/compiler/pull/265)).
Пример:

#include <a_samp>

PrintInt(x)
printf("%d", x);

main()
{
PrintInt(0.0); // warning 213: tag mismatch: expected tag none ("_"), but found "Float"
}

Добавлен новый варнинг для бессмыссленных комбинаций спецификаторов класса (#246 (https://github.com/pawn-lang/compiler/pull/246)).
Примеры:

#include <a_samp>

// Знак "..." означает произвольное количество аргументов (например, как в printf()).
// Аргументы, передаваемые таким образом, недоступны для изменения стандартными
// способами, поэтому спецификатор класса const для них не имеет смысла.
PrintInt(const ...) {}

main()
{
// warning 238: meaningless combination of class specifiers (const variable arguments)
PrintInt(0);
}


#include <a_samp>

// "&" означает, что аргумент "x" передаётся по ссылке и функция может косвенно
// вернуть значение через этот аргумент, однако атрибут const не позволит
// изменить значение переменной, поэтому передача по ссылке бессмысленна.
PrintInt(const &x)
printf("%d", x);

main()
{
new val = 0;
// warning 238: meaningless combination of class specifiers (const reference)
PrintInt(val);
}

Улучшена кодогенерация для функций с атрибутом naked (#271 (https://github.com/pawn-lang/compiler/pull/271)).

Оптимизации для более быстрой компиляции (#255 (https://github.com/pawn-lang/compiler/pull/255), #269 (https://github.com/pawn-lang/compiler/pull/269)).
Изменения заметны при использовании больших массивов, инициализированных неоднородными значениями. Например, для инклуда modelsizes.inc (https://github.com/Crayder/Model-Sizes-Plus) время компиляции удалось уменьшить с 13.7 до 0.95 секунд.

Изменена реализация хеш-таблицы из-за проблем с лицензией (https://github.com/pawn-lang/compiler/issues/239) в предыдущей реализации (#240 (https://github.com/pawn-lang/compiler/pull/240)).

Версия библиотеки времени выполнения Visual C++ сменена обратно на 2010, что позволит запускать компилятор на более широком спектре систем на базе Windows без требования установки дополнительных библиотек.
В предыдущих версиях добавление хеш-таблицы потребовало перехода на VC++ Runtime 2012, однако с новой реализацией хеш-таблицы (см. выше) данное требование пропало.

Исправлено необоснованное использование 128 Мб ОЗУ под хеш-таблицу для глобальных символов, кол-во слотов при запуске снижено с 16'777'216 до 16384.

Исправлены баги, связанные с работой оператора tagof (#245 (https://github.com/pawn-lang/compiler/pull/245), #274 (https://github.com/pawn-lang/compiler/pull/274)).
Один из кейсов уже обсуждался здесь (http://pro-pawn.ru/showthread.php?12257&p=75432&viewfull=1#post75432).

Исправлены баги, связанные с работой деструкторов (#260 (https://github.com/pawn-lang/compiler/pull/260)).
Да, в Pawn, оказывается, есть деструкторы.

Исправлены некорректные значения констант __compat и debug при использовании #pragma option (#253 (https://github.com/pawn-lang/compiler/pull/253)).

Исправлено падение компилятора при вызове функции с более чем 128 аргументами (#298 (https://github.com/pawn-lang/compiler/pull/298)).

Исправлено падение при использовании #pragma deprecated без указания текста сообщения.

Исправлено неправильное декодирование аргумента инструкции switch в листингах, выдаваемых дизассемблером (pawndisasm) (#236 (https://github.com/pawn-lang/compiler/pull/236)).

Исправлен баг в инициализации многомерных массивов, вызывавший падение компилятора в некоторых случаях (#220 (https://github.com/pawn-lang/compiler/pull/220)).

Исправлено форматирование многострочных сообщений от директив #pragma в выводе компилятора.

Daniel_Cortez
30.06.2018, 22:49
Вышел релиз 3.10.8, состоящий из багфиксов и отмены изменений из предыдущего релиза, нарушаюших совместимость.

Скачать: https://github.com/pawn-lang/compiler/releases/tag/v3.10.8

Изменения:
Исправлена обработка пробелов при продолжении строк.
Например, эта строка

new str[] = "Hello \
there";

снова понимается компилятором как "Hello there", а не "Hello   there".

Убрано продолжение строк в однострочных комментариях.
К примеру, следующий код снова будет выдавать ошибку:

// Это комментарий\
и это тоже


Добавлено исключение к приведённому выше правилу.
Компилятор не выдаст ошибку, если после знака переноса "\" следующая строка начинается с "//".

// Это комментарий\
// и это тоже

Это исключение упрощает комментирование кода, использующего продолжение строк (пример: макросы).

В варнинг о несовпадении тегов добавлено больше информации.

native printf(str[], {Float, _}:...);

main()
{
new File:a;
printf("%d", a);
}

Вывод компилятора:


warning 213: tag mismatch: expected tags "Float", or none ("_"); but found "File"


Исправлена обработка продолжения строк в препроцессорных сообщениях.

#pragma deprecated Please\
use\
something\
else
Func() {}

main()
{
Func();
}

Вывод:


warning 234: function is deprecated (symbol "Func") Please use something else

Обратите внимание: в отличие от строк, которым для совместимости было возвращено старое поведение при переносе, здесь знаки переноса заменяются на пробелы.

Исправлена обработка продолжений в макросах (возвращено старое поведение).
Следующий пример больше не объявляет макрос с названием "MACRO5", а создаёт макрос "MACRO" со значением "5".

#define MACRO\
5

Daniel_Cortez
29.09.2018, 22:27
Вышла версия 3.10.9. Как и в прошлый раз, нынешний релиз состоит в основном из багфиксов, но на этот раз есть и пара примечательных нововведений.

Скачать: https://github.com/pawn-lang/compiler/releases/tag/v3.10.9

Изменения:
Добавлены подсказки для случаев, когда пользователь сделал опечатку в названии переменных, функций и т.д.
Пример:

new var = 1;
printf("%d", val); // error 017: undefined symbol "val"; did you mean "var"?

Обратите внимание: после сообщения о необъявленном названии появилось "did you mean "var"?" (пер.: "вы имели в виду "var"?").
Подобные подсказки работают для переменных, констант, функций, меток, автоматонов и состояний, у которых длина названия не меньше 2 символов.

Добавлена выдача варнингов 214 и 239, связанных с ошибками const-корректности (http://pro-pawn.ru/showthread.php?16434), которые выдаются, когда объявленная на месте использования строка передаётся в функцию, но аргумент-массив не объявлен как const.

#include <a_samp>

PrintString(str[]) // warning 214: possibly a "const" array argument was intended: "str"
{
print(str);
}

main()
{
// Строка "test" по сути является неизменяемым массивом, но аргумент str
// в функции PrintString объявлен без атрибута const.
PrintString("test"); // warning 239: literal array/string passed to a non-const parameter
}

Чтобы в данном примере компилятор не выдавал варнинг, следует исправить заголовок функции
PrintString(str[])
PrintString(const str[])
Данные предупреждения работают для всех типов функций, кроме public и native, т.к. много варнингов 214 и 239 выдаётся из-за некорректных заголовков функций в инклудах SA-MP (разработчики компилятора выбрали самый простой вариант и отключили варнинги для public и native, ибо глупо надеяться, что Kalcor исправит те баги).

Исправлено неправильное вычисление результата в цепочках константных (вычисляемых на этапе компиляции) выражений.
Пример:

const SOME_VALUE = 20;
if (10 < SOME_VALUE < 30) // Условие никогда не выполнялось, хоть и должно выдавать true

Исправлено падение компилятора при указании необъявленной константы в качестве размера массива.

new arr[10][unk][10]; // Здесь "unk" - название константы, которую забыли объявить

Исправлена ошибка, из-за которой компилятор пытался сгенерировать вызов несуществующего деструктора.

forward operator~(Error:right[], size); // Деструктор объявлен, но не реализован
main() {
new Error:e; // При уничтожении переменной "e" компилятор сделает вызов несуществующего деструктора
}

Дизассемблер (pawndisasm) больше не выводит лишние пробелы после инструкций, не имеющих параметров.

123
30.09.2018, 07:59
После обновления компилятора до версии 3.10.9, вылезло миллион варнингов типа 214 и 239. Ладно в моем моде, но и в сторонних инклудах типа foreach. И зачем этого было делать? Полезности это не несет.

VVWVV
30.09.2018, 08:49
После обновления компилятора до версии 3.10.9, вылезло миллион варнингов типа 214 и 239. Ладно в моем моде, но и в сторонних инклудах типа foreach. И зачем этого было делать? Полезности это не несет.

Я тоже был поражен, когда заметил, что подобная особенность была включена по умолчанию. Более печальнее еще то, что выключить это, как я понял, невозможно. Как минимум, я не нашел в коде или пулл реквесте ничего, что могло бы отвечать за отключение предупреждений.

bullplex
30.09.2018, 13:56
Я тоже был поражен, когда заметил, что подобная особенность была включена по умолчанию. Более печальнее еще то, что выключить это, как я понял, невозможно. Как минимум, я не нашел в коде или пулл реквесте ничего, что могло бы отвечать за отключение предупреждений.

#pragma warning disable 239
#pragma warning disable 214

Daniel_Cortez
30.09.2018, 14:00
И зачем этого было делать? Полезности это не несет.

Я тоже был поражен, когда заметил, что подобная особенность была включена по умолчанию.
Я и сам не фанат этого изменения, но сделано оно было не просто так.
Представим такую ситуацию:

#include <a_samp>

PrintString(str[])
{
print(str);
str[0]++;
}

PrintHello()
{
PrintString("hello");
}

main()
{
PrintHello();
PrintHello();
}

Если при первом вызове PrintHello() будет выведено "hello", как и задумывалось, то при втором строка уже будет искажена ("iello").
Проблема в том, что "hello" - это неизменяемый массив, объявленный на месте использования (т.е. внутри вызова PrintString()), но в то же время в функции PrintString() аргумент "str[]" является изменяемым (ибо перед ним нет const) - т.е. из-за недосмотра со стороны автора языка Pawn компилятор позволяет передать константный массив как изменяемый, а дальще функция PrintString() может делать с ним что угодно.

Для сравнения, если объявить "hello" явным образом (т.е. как именованный константный массив), компилятор не позволит передать его в PrintString():

PrintHello()
{
static const str[] = "hello";
PrintString(str); // error 035: argument type mismatch (argument 1)
}




Ладно в моем моде, но и в сторонних инклудах типа foreach.
Советую не сеять панику, ещё и дня не прошло с момента релиза.
Более чем уверен, что в инклудах ошибки исправят быстро - либо это сделают сами авторы инклудов, либо другие заинтересованные в исправлении скриптеры.
К примеру, я уже создал PR с исправлениями для mxINI: https://github.com/Open-GTO/mxINI/pull/1



Более печальнее еще то, что выключить это, как я понял, невозможно.
Исправить ошибки в своём коде, нет? (А именно ошибками они и являются. Хорошо ещё, что компилятор в таких ситуациях выдаёт только варнинги, а не ошибки, как с явно объявленными массивами.)
Пример исправления я показал выше.

На крайняк, если не хочется ждать, пока ошибки исправят в инклудах, можно в самое начало мода поставить такую заглушку:

#if defined __PawnBuild
#if __Pawn == 0x3A && __PawnBuild >= 9 || __Pawn > 0x3A
#pragma warning disable 214
#pragma warning disable 239
#endif
#endif

хотя что-то мне подсказывает, что вместо крайнего решения эта заглушка станет раком похуже, чем #pragma tabsize 0.

Kovshevoy
30.09.2018, 14:27
Было 272 варнинга, полазил в парочке инклудов добавил const и уже их нет, на самом деле его легко фиксить, хорошая обновка, пойду ещё паблики прошерстю и туда подобавляю)0

UPD: Error 025 выдает, видно не судьбааа

VVWVV
30.09.2018, 14:28
хотя что-то мне подсказывает, что вместо крайнего решения эта заглушка станет раком похуже, чем #pragma tabsize 0.

Вот и я об этом же.


Исправить ошибки в своём коде, нет? (А именно ошибками они и являются. Хорошо ещё, что компилятор в таких ситуациях выдаёт только варнинги, а не ошибки, как с явно объявленными массивами.)

Можно, но... ты думаешь большие проекты будут это делать? Ошибка и предупреждение - разные вещи. В этом случае он обязан выдать предупреждение, а не ошибку.

Kovshevoy
30.09.2018, 14:32
Можно, но... ты думаешь большие проекты будут это делать? Ошибка и предупреждение - разные вещи. В этом случае он обязан выдать предупреждение, а не ошибку.

Я думаю, что некая часть больших проектов не знает о существовании других версий компилятора и сидит на стандартном, который папке pawno идет с архивом. Но, это всего лишь предположение.
Да и как бы, правильней юзать const, почему бы и не поубирать варнинги, это не особо трудно.

VVWVV
30.09.2018, 14:35
Я думаю, что некая часть больших проектов не знает о существовании других версий компилятора и сидит на стандартном, который папке pawno идет с архивом. Но, это всего лишь предположение.
Да и как бы, правильней юзать const, почему бы и не поубирать варнинги, это не особо трудно.

1) Есть разработчики, которые используют новый компилятор.
2) Стоп, я не говорил, что использовать const - неправильно. Не все разработчики библиотек будут это делать, поскольку есть те, которые уже не выкладывают обновления, а фиксить их же код ... Многие новые фичи можно отключить, но это предупреждение нельзя.

P.S. хотя бессмысленно продолжать данный диалог, лишь потому, что я уже не использую ни один компилятор.

Kovshevoy
30.09.2018, 14:37
1) Есть разработчики, которые используют новый компилятор.
2) Стоп, я не говорил, что использовать const - неправильно. Не все разработчики библиотек будут это делать, поскольку есть те, которые уже не выкладывают обновления, а фиксить их же код ...

Ну, у меня лично более двухста варнингов было из-за инклуда easyDialog
Было: stock Dialog_Open(playerid,function[], style,caption[],info[],button1[],button2[], {Float,_}:...)
Стало: stock Dialog_Open(playerid, const function[], style, const caption[], const info[], const button1[], const button2[], {Float,_}:...)

Сразу минус 250 варнигов, фиксить чей-то код, всего лишь пятью символами в заголовке функции - думаю не такой тяжкий труд.

Daniel_Cortez
30.09.2018, 14:48
Можно, но... ты думаешь большие проекты будут это делать?
Я этого не говорил.



Ошибка и предупреждение - разные вещи. В этом случае он обязан выдать предупреждение, а не ошибку.
Так о том и речь, что варнинги вместо ошибок сделали чисто для совместимости - скрипты всё ещё компилируются, а сами варнинги и заглушить можно.



Было 272 варнинга, полазил в парочке инклудов добавил const и уже их нет, на самом деле его легко фиксить, хорошая обновка, пойду ещё паблики прошерстю и туда подобавляю)0

UPD: Error 025 выдает, видно не судьбааа
public-функции исправлять не нужно, для них варнинги 214 и 239 отключены.


P.S.: Может быть стоит создать отдельную тему со ссылками на самые популярные инклуды и плагины и там отслеживать их совместимость с последней версией компилятора?

VVWVV
30.09.2018, 14:53
Так о том и речь, что варнинги вместо ошибок сделали чисто для совместимости - скрипты всё ещё компилируются, а сами варнинги и заглушить можно.

Я не думаю, что это чисто ради совместимости. Было бы глупо видеть ошибку о работающем коде (он работает, но небезопасно).



public-функции исправлять не нужно, для них варнинги 214 и 239 отключены.

Хм.. я либо уже забыл пуфн, либо паблик функции не содержат ошибок?



P.S.: Может быть стоит создать отдельную тему со ссылками на самые популярные инклуды и плагины и там отслеживать их совместимость с последней версией компилятора?

Было бы здорово.

p.s: странно, что скрытый выход за пределы массива еще не убрали.

Kovshevoy
30.09.2018, 15:00
P.S.: Может быть стоит создать отдельную тему со ссылками на самые популярные инклуды и плагины и там отслеживать их совместимость с последней версией компилятора?

Хорошая идея. Ещё можно функции поправить, которые уже есть на форуме.

Daniel_Cortez
30.09.2018, 15:17
Хорошая идея. Ещё можно функции поправить, которые уже есть на форуме.
Свою функцию IsRPNick (http://pro-pawn.ru/showthread.php?7528) я заранее исправил ещё в июле.
На проверку всех функций на форуме у меня времени нет. Если будут проблемы с const-корректностью - сообщайте в этой теме или в ЛС. Инициатива с самостоятельной подготовкой исправлений также приветствуется.



Многие новые фичи можно отключить, но это предупреждение нельзя.
Можно же, выше есть код.



Было бы глупо видеть ошибку о работающем коде (он работает, но небезопасно).
Так потому и сделали варнинг, что код написан опасным способом?



Хм.. я либо уже забыл пуфн, либо паблик функции не содержат ошибок?
Содержат, но разработчики компилятора прогнулись под забагованные инклуды SA-MP и отключили варнинги для функций native и public.



p.s: странно, что скрытый выход за пределы массива еще не убрали.
А вот об этом подробнее, пожалуйста.

VVWVV
30.09.2018, 15:25
Можно же, выше есть код.
Тот же gcc не выдает такие предупреждения, хотя, насколько я помню, там можно включить отображение это.


Так потому и сделали варнинг, что код написан опасным способом?
Он не такой уж и опасный.


Содержат, но разработчики компилятора прогнулись под забагованные инклуды SA-MP и отключили варнинги для функций native и public.
Вот это вообще превосходно. Я уже много раз высказывал свое мнение о том, что компилятор использует нестандартные, даже глупые способы для реализации своих фич.


А вот об этом подробнее, пожалуйста.

static some_array[][] = {
{1,2},
{3,4,5,6}
};
main() {
printf("Result: %d", some_array[0][4]); // Output: Result: 5
}

Daniel_Cortez
30.09.2018, 16:29
static some_array[][] = {
{1,2},
{3,4,5,6}
};
main() {
printf("Result: %d", some_array[0][4]); // Output: Result: 5
}

А, так это давно известный баг: если кол-во столбцов не фиксированное, компилятор его не запоминает и не контролирует индексы при обращении к массиву.
Очень много изменений нужно, чтобы исправить такое, поэтому неудивительно, что этот недочёт не исправлен до сих пор.



Тот же gcc не выдает такие предупреждения, хотя, насколько я помню, там можно включить отображение это.
Ну так там и уровни предупреждений есть (основные, дополнительные), которых в pawnc нет.



Он не такой уж и опасный.
Спорный вопрос, ситуации разные бывают.



Вот это вообще превосходно. Я уже много раз высказывал свое мнение о том, что компилятор использует нестандартные, даже глупые способы для реализации своих фич.
Я уже давно говорил, что не стоит воспринимать тех разработчиков как какой-то "комитет по стандартизации Pawn" - даже если их группа на GitHub и называется "pawn-lang", на деле они заинтересованы в развитии языка только в угоду совместимости с багами SA-MP.
В результате имеем, что имеем: один очень упёртый человек, не желающий исправлять баги (пока они не повлияют на выручку с "Hosted") и грозящийся забросить МП, важнее, чем всё сообщество вместе взятое.

Daniel_Cortez
01.10.2018, 18:47
Создал тему со списком инклудов и плагинов (http://pro-pawn.ru/showthread.php?16427), обо всех новых варнингах в инклудах просьба сообщать в ней.

Kovshevoy
15.03.2019, 00:22
Йоу, хочу запостить темку с указанием источника и авторства на другой пуфн форум, можно получить разрешение?

Seviel
17.03.2019, 18:17
Заметил небольшой баг в компиляторе(3.10.8), когда переменную объявляешь в инклуде и она не используется. То компилятор указывает строку в моде, а не в инклуде.

DeimoS
17.03.2019, 18:27
Заметил небольшой баг в компиляторе(3.10.8), когда переменную объявляешь в инклуде и она не используется. То компилятор указывает строку в моде, а не в инклуде.

Это, если что, не баг этой версии компилятора, а в целом проблема компилятора, которая прослеживается и на компиляторе, идущем вместе с официальной серверной сборкой.

Daniel_Cortez
20.03.2019, 09:10
Йоу, хочу запостить темку с указанием источника и авторства на другой пуфн форум, можно получить разрешение?
Не совсем понимаю, о каком указании источника может идти речь. На других "пуфн-форумах" (по крайней мере, на всех, что я видел раньше) сейчас модно запрещать ссылки на другие похожие форумы.



Заметил небольшой баг в компиляторе(3.10.8), когда переменную объявляешь в инклуде и она не используется. То компилятор указывает строку в моде, а не в инклуде.

Это, если что, не баг этой версии компилятора, а в целом проблема компилятора, которая прослеживается и на компиляторе, идущем вместе с официальной серверной сборкой.
Это не совсем одно и то же. В стандартной версии и вплоть до 3.10.7 в сообщениях о неиспользуемых переменных компилятор указывал название основного файла скрипта и последний номер строки в нём (например, вместо "include.inc:24" выводилось "mode.pwn:4999", где 4999 - номер последней строки в mode.pwn). Затем Zeex попытался исправить этот баг, но он оказался исправлен только для переменных, объявленных в основном файле. Если же переменная объявлена в инклуде, компилятор выводит правильный номер строки из инклуда, но вместо названия инклуда указывает имя основного файла (т.е. например вместо "include.inc:24" получается "mode.pwn:24").

Если что, в репо компилятора всё ещё открыт issue для этого бага: https://github.com/pawn-lang/compiler/issues/305

Kovshevoy
20.03.2019, 19:00
Не совсем понимаю, о каком указании источника может идти речь. На других "пуфн-форумах" (по крайней мере, на всех, что я видел раньше) сейчас модно запрещать ссылки на другие похожие форумы.


На том форуме не запрещено указывать источник если это не "нами горячо любимый форум"

Salik_Davince
23.03.2019, 10:00
UPD: Извеняюсь, это из за compress мода, кстати почему он вообще нужен (точнее как он сжимает исходный файл?).

Без параметра compress 0 | мод весит нормально и с варнингом
warning 232: output file is written, but with compact encoding disabled

Но с ним он весит гораздо больше но без варнинга.

UPDD: В версии 10.9 в любом состоянии без компресса или же с ним, мод весит гораздо больше.

Daniel_Cortez
23.03.2019, 20:10
Во-первых, сжимается не исходный файл, а бинарный (скомпилированный).
Во-вторых, да, такое редко, но может произойти, когда компилятор при попытке сжатия обнаруживает, что размер буфера для сжатия/распаковки данных слишком мал (и расширить его не вариант, размер фиксированный), и записывает скомпилированный файл в неупакованном виде. Обычно причиной этому используемые в вашем скрипте инклуды.

Salik_Davince
20.05.2019, 03:15
Странно это из за Pawn?

Комманды как то не правильно выполняют свою руль, т.e условные значения так же (сорян если что-то пишу не так), лучше приведу пример -

CMD:support(playerid, params[])
{
if(Player[playerid][admin] >= 1 || Player[playerid][support] >= 1)
{
SendClientMessage(playerid, -1, "Да тут должно заработать если я Админ либо Саппорт, так ведь?");
return true
}
else
return SendClientMessage(playerid, col_gray, "У вас не достаточно прав для использования данной команды.");
//Но выводит это сообщение, если я Админ либо Саппорт!
//Работает пока по другому принципу, Если выдать и Админа и Саппорта одновременно то команда будет работать, это баг Pawn?
}


P.S Использовал версию 10.6*вроде, на новую тоже не такой уж вариант, т.к с ними мод весит 80мб+, кстати можете объяснить почему так высоко взлетел размер .amx файла?

P.S.S Откатился на версию 10.4, пока что все нормально.

Daniel_Cortez
20.05.2019, 22:04
На счёт if - чтобы разобраться, в чём проблема, мне нужно знать, какой байткод генегируется из исходного текста, а для этого нужен либо минимальный воспроизводимый пример (т.е. не привязанный к вашему моду), либо сам мод.
Касаемо проблемы с весом скрипта - да, в 3.10.5 я вносил изменения в алгоритм упаковки, чтобы ускорить компиляцию скриптов, при этом проверял на нескольких модах (на всех сгенерированные файлы *.amx со стандартным и изменённым алгоритмами совпадали до единого байта). Ваш случай выглядит как что-то специфическое (т.к. до вас мне не желовались на проблемы с упаковкой только в новых версиях), поэтому мне понадобится ваш мод, чтобы воспроизвести баг.

ziggi
21.05.2019, 00:33
Во-первых, сжимается не исходный файл, а бинарный (скомпилированный).
Во-вторых, да, такое редко, но может произойти, когда компилятор при попытке сжатия обнаруживает, что размер буфера для сжатия/распаковки данных слишком мал (и расширить его не вариант, размер фиксированный), и записывает скомпилированный файл в неупакованном виде. Обычно причиной этому используемые в вашем скрипте инклуды.

Мне это удалось пофиксить простой пересборкой компилятора на своей машине.


Касаемо проблемы с весом скрипта - да, в 3.10.5 я вносил изменения в алгоритм упаковки, чтобы ускорить компиляцию скриптов, при этом проверял на нескольких модах (на всех сгенерированные файлы *.amx со стандартным и изменённым алгоритмами совпадали до единого байта). Ваш случай выглядит как что-то специфическое (т.к. до вас мне не желовались на проблемы с упаковкой только в новых версиях), поэтому мне понадобится ваш мод, чтобы воспроизвести баг.

Я писал в ЛС с этим)

Salik_Davince
21.05.2019, 00:38
Могу скинуть Мод, есть телеграмм?

Daniel_Cortez
30.05.2019, 21:26
Похоже, опасения подтвердились: в функции упаковки был баг, из-за чего в очень редких случаях компилятор ложно считал, что размер буфера распаковки превышен, и отключал упаковку данных.

Пока что я тестирую исправление, в ближайшее время подготовлю PR в репо компилятора (если нужно, могу и в этой теме выложить неофициальный релиз с фиксом, чтобы не ждать выхода новой версии компилятора несколько месяцев). Приношу свои извинения всем, кому этот баг мог доставить неудобства.

Salik_Davince
31.05.2019, 13:57
На счет компилятора - если конечно можно, то да.

Daniel_Cortez
06.06.2019, 20:43
Неофициальный релиз 3.10.9+ (выдаёт себя как просто "3.10.9", ибо я был слишком ленив, чтобы добавить "+" в код).
Отличия от 3.10.9:
Исправлен выход за пределы массива в функции упаковки данных, из-за которого ложно выдавалось сообщение "warning 232: output file is written, but with compact encoding disabled".

Исправлен баг, из-за которого компилятор при опечатке предлагал переменную до того, как она была реализована (#374 (https://github.com/pawn-lang/compiler/pull/374)).

GetValue()
{
return value; // error 017: undefined symbol "value"; did you mean "value"?
// Очевидно, что переменная "value" не должна быть видна отсюда, т.к. она объявлена только ниже.
}

new value = 0;

main()
{
GetValue();
}

Исправлен баг, из-за которого компилятор при опечатке не предлагал функцию, если ошибка допущена перед реализацией функции (#397 (https://github.com/pawn-lang/compiler/pull/397)).

main()
{
// Здесь компилятор должен предложить функцию "DoNothing", но он этого не делает,
// хоть в Pawn функции и могут вызываться до своего объявления и реализации.
DoNothin(); // error 017: undefined symbol "DoNothin"
}

DoNothing(){}


https://www.dropbox.com/s/3fa3ak5ewfuu577/pawnc-3.10.9-fixed.zip?dl=0
Обо всех проблемах просьба незамедлительно сообщать в эту тему или в ЛС.

vasyok28
16.06.2019, 14:15
Решил обновиться и начало кидать большую тучу ошибок:
\pawno\include\foreach.inc(895) : warning 214: possibly a "const" array argument was intended: "array"
\pawno\include\MxINI.inc(323) : warning 214: possibly a "const" array argument was intended: "szFilePath"
include\MxINI.inc(530) : warning 214: possibly a "const" array argument was intended: "szKeyName"
warning 239: literal array/string passed to a non-const parameter
warning 239: literal array/string passed to a non-const parameter

В чем проблема может быть ?

DeimoS
16.06.2019, 16:27
Решил обновиться и начало кидать большую тучу ошибок:
\pawno\include\foreach.inc(895) : warning 214: possibly a "const" array argument was intended: "array"
\pawno\include\MxINI.inc(323) : warning 214: possibly a "const" array argument was intended: "szFilePath"
include\MxINI.inc(530) : warning 214: possibly a "const" array argument was intended: "szKeyName"
warning 239: literal array/string passed to a non-const parameter
warning 239: literal array/string passed to a non-const parameter

В чем проблема может быть ?

В том, что кто-то не прочёл до конца тему. Причина и исправление ошибок уже обсуждались.

Daniel_Cortez
20.07.2019, 19:10
Ещё один неофициальный релиз 3.10.9+ (тоже выдаёт себя за обычный "3.10.9").

Новые исправления:
Устранён краш из-за пустого текста в #warning и #error (#369 (https://github.com/pawn-lang/compiler/pull/369)).

Исправлен баг, из-за которого при выводе warning 224 ("массив в sizeof имеет неопределённый размер") не отображалось название массива (#370 (https://github.com/pawn-lang/compiler/pull/370)).

Устранён краш дизассемблера (pawndisasm) из-за неправильных инструкций (#424 (https://github.com/pawn-lang/compiler/pull/424)).

Исправлены некорректные предложения (обычно выдаются при опечатках), выдаваемые для переменных, имеющих состояние (#431 (https://github.com/pawn-lang/compiler/pull/431)).

Исправлен баг с возможностью инициализировать локальные переменные самими собой при объявлении (#436 (https://github.com/pawn-lang/compiler/pull/436)).

Скачать: https://www.dropbox.com/s/3fa3ak5ewfuu577/pawnc-3.10.9-fixed.zip?dl=0
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

DeimoS
07.08.2019, 10:52
Как насчёт того, чтоб в основном посте оставить ссылку на исправленные стандартные инклуды, по типу этих (https://github.com/sampctl/samp-stdlib)?

UPD: А лучше, как по мне, нечто подобное так же и на сайте wiki.pro-pawn.ru разместить, чтоб появилось место, где всегда можно найти актуальную версию исправленных инклудов.

Daniel_Cortez
08.08.2019, 20:03
Как насчёт того, чтоб в основном посте оставить ссылку на исправленные стандартные инклуды, по типу этих (https://github.com/sampctl/samp-stdlib)?
Со следующим релизом именно так и хотел сделать. Правда, непонятно, когда этот релиз ещё будет и будет ли вообще; ИМХО, накопившихся за год нововведений и исправлений могло бы хватить не то, чтобы на один - на три релиза.
Если в предыдущих релизах были костыли для совместимости со стандартными инклудами (например, сообщение о const-корректности warning 239 специально было отключено для нативных функций, т.к. некоторые функции SA-MP были объявлены некорректно), то сейчас сопровождающие проекта больше придерживаются мнения, что эта совместимость не нужна, т.к. теперь есть исправленные инклуды (к примеру, Y_Less высказывался (https://github.com/pawn-lang/compiler/pull/440#issuecomment-515155836), что эта совместимость больше ни к чему; да и взять то же ограничение warning 239 - пару дней назад я сделал PR (https://github.com/pawn-lang/compiler/pull/441), который это ограничение удаляет, и этот PR практически сразу же одобрили).


UPD: А лучше, как по мне, нечто подобное так же и на сайте wiki.pro-pawn.ru разместить, чтоб появилось место, где всегда можно найти актуальную версию исправленных инклудов.
Для этого нужно сначала создать что-то вроде нового раздела ("Программное обеспечение"? "Программы/утилиты для скриптинга"?) и по-хорошему заполнить его несколькими статьями, в том числе про компилятор (уже готовое содержимое есть в 1-м посте).
Я бы и сам это сделал, но почти всё свободное время уходит на эксперименты с новыми фичами для компилятора.

vvw
09.08.2019, 01:50
Со следующим релизом именно так и хотел сделать. Правда, непонятно, когда этот релиз ещё будет и будет ли вообще; ИМХО, накопившихся за год нововведений и исправлений могло бы хватить не то, чтобы на один - на три релиза.
Если в предыдущих релизах были костыли для совместимости со стандартными инклудами (например, сообщение о const-корректности warning 239 специально было отключено для нативных функций, т.к. некоторые функции SA-MP были объявлены некорректно), то сейчас сопровождающие проекта больше придерживаются мнения, что эта совместимость не нужна, т.к. теперь есть исправленные инклуды (к примеру, Y_Less высказывался (https://github.com/pawn-lang/compiler/pull/440#issuecomment-515155836), что эта совместимость больше ни к чему; да и взять то же ограничение warning 239 - пару дней назад я сделал PR (https://github.com/pawn-lang/compiler/pull/441), который это ограничение удаляет, и этот PR практически сразу же одобрили).
Такая неразбериха происходит из-за того, что люди не могут понять, чего они хотят. Я забил на это после того, как Zeex замержил мой PR... когда он был в состоянии WIP. Хотя после этого они начали делать тесты, что довольно похвально.
Релизы они выпускают хаотично. Нет никакого регламента (хотя бы самого простого: если есть 3-5 исправлений в течении 3 месяцев - выпускаем релиз в конце этих 3 месяцев).


Для этого нужно сначала создать что-то вроде нового раздела ("Программное обеспечение"? "Программы/утилиты для скриптинга"?) и по-хорошему заполнить его несколькими статьями, в том числе про компилятор (уже готовое содержимое есть в 1-м посте).
Я бы и сам это сделал, но почти всё свободное время уходит на эксперименты с новыми фичами для компилятора.
ИМХО не вижу смысла изобретать что-то новое. Тот же compuphase забил на него. __emit оператором никто не пользуется (можно было переписать всю библиотеку amx_assembly, сделав ее код более лучше; либо сделать его поддержку в YSI).

Daniel_Cortez
09.08.2019, 21:37
Такая неразбериха происходит из-за того, что люди не могут понять, чего они хотят. Я забил на это после того, как Zeex замержил мой PR... когда он был в состоянии WIP.
Ну во-первых, он это сделал, когда сам только отказался от работы над форком, поэтому недостаток внимания на тот момент можно понять.
Во-вторых, можно было в начале описания PR оставить примечание, что-нибудь вроде:

### [DO NOT MERGE - WORK IN PROGRESS]
как, к примеру, было сделано в #303 (https://github.com/pawn-lang/compiler/pull/303).



если есть 3-5 исправлений в течении 3 месяцев - выпускаем релиз в конце этих 3 месяцев
Да уж лучше бы так и было. Сейчас вообще за год ни одного изменения, хотя изменений накопилось, хоть отбавляй :)



ИМХО не вижу смысла изобретать что-то новое. Тот же compuphase забил на него.
В compuphase могли быть свои причины. Здесь же речь о форке Pawn 3.2, в котором накопилось достаточно много багфиксов и новых фич в сравнении с оригиналом. И на эти фичи есть спрос, т.к. сообщество SA-MP ещё далеко от полного вымирания, сколько бы усилий Kalcor не прилагал.
Если же речь конкретно о моих мотивах, то для меня это просто хорошая возможность для 1) развития собственных навыков программирования; и 2) применения на практике знаний в области англ. языка для общения с другими опытными скриптерами. К тому же, этому форку Pawn помимо SA-MP можно найти другие применения.



__emit оператором никто не пользуется (можно было переписать всю библиотеку amx_assembly, сделав ее код более лучше; либо сделать его поддержку в YSI).
Оператором __emit изначально не пользовались в первую очередь из-за отсутствия какой-либо документации - ни в wiki в репозитории, ни статей на зарубежных форумах, ничего. Есть статья на этом форуме и я оставлял на неё ссылку в репо компилятора, но никто не хочет её переводить, т.к. оператором не пользуются. Ловушка 22.

vvw
09.08.2019, 22:18
Ну во-первых, он это сделал, когда сам только отказался от работы над форком, поэтому недостаток внимания на тот момент можно понять.
Во-вторых, можно было в начале описания PR оставить примечание, что-нибудь вроде:

### [DO NOT MERGE - WORK IN PROGRESS]
как, к примеру, было сделано в #303 (https://github.com/pawn-lang/compiler/pull/303).

Мерджить не протестированный бенч... такое себе. А вообще мы вроде бы об этом в джаббер с тобой говорили.


В compuphase могли быть свои причины. Здесь же речь о форке Pawn 3.2, в котором накопилось достаточно много багфиксов и новых фич в сравнении с оригиналом. И на эти фичи есть спрос, т.к. сообщество SA-MP ещё далеко от полного вымирания, сколько бы усилий Kalcor не прилагал.
Оно умирает.


Если же речь конкретно о моих мотивах, то для меня это просто хорошая возможность для 1) развития собственных навыков программирования; и 2) применения на практике знаний в области англ. языка для общения с другими опытными скриптерами. К тому же, этому форку Pawn помимо SA-MP можно найти другие применения.
Про твои мотивы я уже давно знаю) Это похвально. Дальнейшего тебе развития) Кстати, спасибо тебе)


Оператором __emit изначально не пользовались в первую очередь из-за отсутствия какой-либо документации - ни в wiki в репозитории, ни статей на зарубежных форумах, ничего. Есть статья на этом форуме и я оставлял на неё ссылку в репо компилятора, но никто не хочет её переводить, т.к. оператором не пользуются. Ловушка 22.
Так у тебя есть возможность подкрепить свои знания в английском языке.

P.S.(0): ты допилил свой проект?
P.S.(1): старый акк можно удалять к чертям, ибо я на него уже не смогу зайти... В порыве избавится от Pawn в моей голове... я изменил пароль на черт его знает какой.

Fallen A.
08.09.2019, 16:48
При создании таймера, если количество аргументов не совпадает, следует ввести напоминание в виде варнинга.
Пример:


SetTimerEx("@__TIMER", 1, true, "d", test, test);

Fallen A.
09.09.2019, 22:38
... В порыве избавится от Pawn в моей голове... я изменил пароль на черт его знает какой.

Pawn не так уж и плох, как язык выходного дня.

Daniel_Cortez
10.09.2019, 06:16
При создании таймера, если количество аргументов не совпадает, следует ввести напоминание в виде варнинга.
Пример:


SetTimerEx("@__TIMER", 1, true, "d", test, test);

Да, приходила в голову подобная идея, как для SetTimerEx()/CallLocalFunction()/CallRemoteFunction(), так и для format()/printf(), тем более в популярных компиляторах для C/C++ (MSVC, GCC, Clang) нечто подобное уже давно есть.
С точки зрения пользователя да, вроде бы простая и полезная фича, но вот как это примерно может выглядеть с точки зрения разработчика:
В компиляторах для тех же C/C++ такая возможность реализуется через нестандартные расширения. Например, в glibc заголовок функции printf() объявлен с постфиксом "__attribute__((format(printf, 1, 2)))".
Следовательно, в компиляторе Pawn сначала потребуется реализовать оператор __attribute (возможность создания этого оператора уже обсуждалась в одном из issue в репо компилятора год назад, поэтому я более чем уверен, что мейнтейнеры будут настаивать именно на таком варианте). У этого оператора одним из возможных аргументов будет format, а у того, в свою очередь параметром будет либо printf (т.е. "__attribute format printf"), либо тот формат спецификаторов, который применим к SetTimerEx()/CallLocalFunction()/CallRemoteFunction() - и если с названием "printf" всё очевидно, для этого формата я понятия не имею, как его можно назвать.
Также непонятно, где можно было бы хранить информацию о нестандартном атрибуте функции (т.е. флаги присутствия атрибутов, позицию форматной строки, и позицию, с которой начинаются соответствующие аргументы). Создавать для этой цели отдельные поля в структуре symbol - такое себе быдлокодерское решение, т.к. это увеличит расход памяти под все виды идентификаторов, т.е. и под функции, и под переменные, и под константы.

И это только те подводные камни, которые я сейчас смог вспомнить сходу; уверен, при попытке реализации всплывёт ещё больше проблем. Я ни в коем случае не утверждаю, что идея сама по себе плохая, но то, что воплотить её будет затруднительно - факт. Я могу взяться за её реализацию, но позже, как только закончу с другими экспериментальными фичами, коих у меня уже скопилось несколько штук в локальном репо.

Fallen A.
10.09.2019, 09:33
Многое, о чем ты говоришь - для меня темный лес, т.к. с c++ не знаком. Однако, рискну предположить, что можно реализовать без хранения и просто при сборке проекта проверять каждую функцию. Если я чего-то недопонимаю, то поправьте меня.

Геннадий Литвинов
10.09.2019, 19:54
Вот если ещё табулирование было как NotePad + то вообще класс было бы ... :blush2:

Pa4enka
10.09.2019, 20:23
Вот если ещё табулирование было как NotePad + то вообще класс было бы ... :blush2:

Эм.. что? Здесь обсуждается компилятор, а не редактор кода.

vvw
11.09.2019, 02:02
Да, приходила в голову подобная идея, как для SetTimerEx()/CallLocalFunction()/CallRemoteFunction(), так и для format()/printf(), тем более в популярных компиляторах для C/C++ (MSVC, GCC, Clang) нечто подобное уже давно есть.
С точки зрения пользователя да, вроде бы простая и полезная фича, но вот как это примерно может выглядеть с точки зрения разработчика:
В компиляторах для тех же C/C++ такая возможность реализуется через нестандартные расширения. Например, в glibc заголовок функции printf() объявлен с постфиксом "__attribute__((format(printf, 1, 2)))".
Следовательно, в компиляторе Pawn сначала потребуется реализовать оператор __attribute (возможность создания этого оператора уже обсуждалась в одном из issue в репо компилятора год назад, поэтому я более чем уверен, что мейнтейнеры будут настаивать именно на таком варианте). У этого оператора одним из возможных аргументов будет format, а у того, в свою очередь параметром будет либо printf (т.е. "__attribute format printf"), либо тот формат спецификаторов, который применим к SetTimerEx()/CallLocalFunction()/CallRemoteFunction() - и если с названием "printf" всё очевидно, для этого формата я понятия не имею, как его можно назвать.
Также непонятно, где можно было бы хранить информацию о нестандартном атрибуте функции (т.е. флаги присутствия атрибутов, позицию форматной строки, и позицию, с которой начинаются соответствующие аргументы). Создавать для этой цели отдельные поля в структуре symbol - такое себе быдлокодерское решение, т.к. это увеличит расход памяти под все виды идентификаторов, т.е. и под функции, и под переменные, и под константы.

И это только те подводные камни, которые я сейчас смог вспомнить сходу; уверен, при попытке реализации всплывёт ещё больше проблем. Я ни в коем случае не утверждаю, что идея сама по себе плохая, но то, что воплотить её будет затруднительно - факт. Я могу взяться за её реализацию, но позже, как только закончу с другими экспериментальными фичами, коих у меня уже скопилось несколько штук в локальном репо.

В структуре symbol для функции уже предоставлен список аргументов со всеми тегами и прочим. Нам нужно лишь сделать универсальный оператор __attribute (format(...)), который будет сообщать строку с форматом и началом переменного кол-ва аргументов (variadic args). Хранить строки вероятно в отдельном списке. Номер ячейки из списка хранить в union x, записав stacksize и идентификатор из таблицы в виде структуры struct func. Памяти будет использовано гораздо меньше, чем мы бы создавали на каждый символ в отдельном поле.

Дополнительный список лучше сделать из-за переменного кол-ва аргументов (их может очень быть много). Можно сделать union для других attribute-параметров.

P.S. мб где-то сказал глупость, но я это так себе представляю.


Pawn не так уж и плох, как язык выходного дня.

Ты прав, он годится только для handmade проектов.

Daniel_Cortez
15.09.2019, 19:43
Ты прав, он годится только для handmade проектов.
Так SA-MP - это по сути и есть handmade-проект.


Нам нужно лишь сделать универсальный оператор __attribute (format(...)), который будет сообщать строку с форматом и началом переменного кол-ва аргументов (variadic args).
Я примерно так и описывал его в своём посте выше, разве что без скобок (они не являются обязательными в defined, sizeof и tagof, поэтому для __attribute есть смысл обеспечить ту же логику).


В структуре symbol для функции уже предоставлен список аргументов со всеми тегами и прочим. Хранить строки вероятно в отдельном списке. Номер ячейки из списка хранить в union x, записав stacksize и идентификатор из таблицы в виде структуры struct func. Памяти будет использовано гораздо меньше, чем мы бы создавали на каждый символ в отдельном поле.
Переменная stacksize объявлена как long - это означает, что в зависимости от компилятора/целевой платформы её размер может быть не только 4, но и 8 байт. Если её и новую переменную объединить в struct, то в сумме их размер может превысить размер struct array.

Как бы то ни было, я только что создал PR'ы с двумя новыми фичами - __addressof (https://github.com/pawn-lang/compiler/pull/445) и __fallthrough (https://github.com/pawn-lang/compiler/pull/446) (последняя, к слову, почему-то не очень нравится мейнтейнерам). На следующих выходных попробую реализовать __attribute, если время позволит.

vvw
16.09.2019, 04:49
Переменная stacksize объявлена как long - это означает, что в зависимости от компилятора/целевой платформы её размер может быть не только 4, но и 8 байт. Если её и новую переменную объединить в struct, то в сумме их размер может превысить размер struct array.
По сути для оператора __attribute нужно будет выделять поле в структуре symbol (указатель, ибо оператор опционален, чтобы хранить всю структуру в symbol), ибо (почти) каждый символ может быть реализован с помощью этого оператора, а специфичную информацию нужно где-то хранить.



Как бы то ни было, я только что создал PR'ы с двумя новыми фичами - __addressof (https://github.com/pawn-lang/compiler/pull/445) и __fallthrough (https://github.com/pawn-lang/compiler/pull/446) (последняя, к слову, почему-то не очень нравится мейнтейнерам). На следующих выходных попробую реализовать __attribute, если время позволит.
Они просто очень любят goto. =) Идея с __addressof очень понравилась :good:

tnc
23.09.2019, 17:00
Не нашел в коде константу, которая отвечает за смещение часового пояса . Она есть? (Это было бы полезно, если делать версии мода датой [__date, __time])

P.S: Если ее нет, то я сделаю PR.

Daniel_Cortez
23.09.2019, 17:58
Не нашел в коде константу, которая отвечает за смещение часового пояса . Она есть? (Это было бы полезно, если делать версии мода датой [__date, __time])

P.S: Если ее нет, то я сделаю PR.
Нет, и впервые вообще приходится слышать о необходимости в чём-то подобном (причём, не только в Pawn, но и даже в C/C++, из которых, собственно, и позаимствованы идеи с __date, __time, __file и __line).
Можно поподробнее о том, как такая константа должна использоваться? Может быть я что-то не так понял.

tnc
23.09.2019, 19:02
Нет, и впервые вообще приходится слышать о необходимости в чём-то подобном (причём, не только в Pawn, но и даже в C/C++, из которых, собственно, и позаимствованы идеи с __date, __time, __file и __line).
Можно поподробнее о том, как такая константа должна использоваться? Может быть я что-то не так понял.

Допустим: использовать дату компиляции скрипта в роле версии мода (https://ru.wikipedia.org/wiki/%D0%9D%D1%83%D0%BC%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B9_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BE%D0%B1%D0%B5%D1%81%D0%BF%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F#%D0%94%D0%B0%D1%82%D0%B0). Если я живу в Екатеринбурге (допустим), то offset + 2 от Москвы. Как раз таки использую дату компиляции мода для версии мода и появилась проблема, что у второго разработчика не московское время, а нужно чтобы показывалось московское.

Daniel_Cortez
24.09.2019, 17:59
Использовать дату и время для версионирования - очень плохая идея. Это не исключает возможности того, что вы и второй разработчик можете в одно и то же (или почти одно и то же) время сделать две разные версии мода с разным новым функционалом/багфиксами. Обычно для таких целей используют хеши коммитов из системы контроля версий, к примеру Git (т.е. можно организовать сборку с помощью файла *.bat или shell-скрипта, и в него перед сборкой добавить вызов git с целью узнать хеш текущего коммита и записать результат в файл *.inc).

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

truescripter
20.12.2019, 00:33
Когда уже компилятор обновят? Есть инфа какая-нибудь? Столько исправлений на гите уже, почему они тянут?

Daniel_Cortez
21.12.2019, 12:44
Когда уже компилятор обновят? Есть инфа какая-нибудь? Столько исправлений на гите уже, почему они тянут?
Пока что от мейнтейнеров проекта не было никаких официальных заявлений на счёт нового релиза. Как я уже говорил раньше, можете потерроризировать их этим вопросом в репо на GitHub (https://github.com/pawn-lang/compiler/issues) :)

vvw
23.12.2019, 01:40
Пока что от мейнтейнеров проекта не было никаких официальных заявлений на счёт нового релиза. Как я уже говорил раньше, можете потерроризировать их этим вопросом в репо на GitHub (https://github.com/pawn-lang/compiler/issues) :)

Просто все мейнтейнеры заняты Advent Of Code. Забавная, кстати, штука.

Daniel_Cortez
28.12.2019, 16:37
Просто все мейнтейнеры заняты Advent Of Code. Забавная, кстати, штука.
Заняты прямо настолько, чтобы последние несколько месяцев не было возможности оставить комментарии в нескольких простых issue или даже просто расставить в них теги? Нет, что-то здесь не стыкуется.

Как бы то ни было, я создал новый PR (https://github.com/pawn-lang/compiler/pull/475), в котором исправлен недочёт с отсутствием проверки на несоответствие тегов между значениями в switch и case (ибо если в тернарных выражениях компилятор может жаловаться на несоответствие тегов, то чем switch/case хуже?). Но готов поспорить, ситуацию это ничуть не изменит и в ближайшие несколько месяцев от мейнтейнеров будет ноль внимания.

Daniel_Cortez
31.12.2019, 14:23
Предновогодний "неофициальный" релиз 3.10.9+ с исправлением багов.

Новые изменения (с момента предыдущего (http://pro-pawn.ru/showthread.php?2207&p=94597&viewfull=1#post94597) неоф. релиза):
Исправлена проблема с неявным игнорированием тегов в анонимных enum (#454 (https://github.com/pawn-lang/compiler/pull/454)).
Отдельная благодарность m1n1vv за то, что сообщил о баге (разбор проблемы: 1 (http://pro-pawn.ru/showthread.php?16871&p=94866&viewfull=1#post94866), 2 (http://pro-pawn.ru/showthread.php?16871&p=94869&viewfull=1#post94869)).

Устранён недочёт с отсутствием проверки на несовпадение тегов между выражениями в switch и case (#475 (https://github.com/pawn-lang/compiler/pull/475)).
Если в тернарных выражениях компилятор жалуется, когда у значений под "?" и ":" разные теги, то чем switch хуже?

Немного ускорен процесс компиляции за счёт упрощения алгоритма отсеивания неиспользуемых переменных/констант/функций.

Скачать: https://www.dropbox.com/s/3fa3ak5ewfuu577/pawnc-3.10.9-fixed.zip?dl=0
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

Kovshevoy
02.01.2020, 14:09
http://prntscr.com/qiew1j
Шо за прыколы
update: fixed http://prntscr.com/qif4g3

Daniel_Cortez
03.01.2020, 18:18
update: fixed http://prntscr.com/qif4g3
На самом деле там, по-хорошему, гораздо больше исправлять нужно: https://github.com/Open-GTO/mdialog/pull/14#issuecomment-570578335
На выходных, если будет время, попробую подготовить фикс, но ничего обещать не могу.

vvw
04.01.2020, 14:50
Так и сделал ты свой форк. =) Для меня твой вариант компилятора становится приоритетнее варианта от Zeex.

Pa4enka
22.01.2020, 19:07
Интересно, а возможно ли расширить функционал компилятора до возможности определять повторяющиеся присвоения переменной в определенном блоке кода? Данное предложения похоже на warning 210 (https://pro-pawn.ru/showthread.php?16839-warning-210-%28-%29), ибо так же анализирует код с его логической стороны.

В двух словах о предложении:

stock SetPlayerDefaultInfo(playerid)
{
// some code

PlayerInfo[playerid][pAdmin] = 0;
PlayerInfo[playerid][pSpawn] = 0;
PlayerInfo[playerid][pLogin] = false;

// ...........

PlayerInfo[playerid][pSpawn] = 1;

return true;
}
Как видим, переменной изначально было присвоено правильное значение, а позже, по ошибке разработчика pSpawn установилось значения 1. Согласитесь, в этой ситуации играет людской фактор. Но хорошо, когда разработчик заметит эту ошибку в процессе тестирования. А если же нет? В обоих случаях придется лезть в код и производить дебаг. Это лишнее время и лишние действия. Было бы круто, если компилятор умел видеть и такие ошибки, ведь:


Такой базовый механизм предотвращения ошибок есть во многих других языках. Во многих, но только не в Pawn - языке с максимальным контролем над ошибками, созданном специально для новичков!

DeimoS
22.01.2020, 20:26
Интересно, а возможно ли расширить функционал компилятора до возможности определять повторяющиеся присвоения переменной в определенном блоке кода? Данное предложения похоже на warning 210 (https://pro-pawn.ru/showthread.php?16839-warning-210-%28-%29), ибо так же анализирует код с его логической стороны.

В двух словах о предложении:

stock SetPlayerDefaultInfo(playerid)
{
// some code

PlayerInfo[playerid][pAdmin] = 0;
PlayerInfo[playerid][pSpawn] = 0;
PlayerInfo[playerid][pLogin] = false;

// ...........

PlayerInfo[playerid][pSpawn] = 1;

return true;
}
Как видим, переменной изначально было присвоено правильное значение, а позже, по ошибке разработчика pSpawn установилось значения 1. Согласитесь, в этой ситуации играет людской фактор. Но хорошо, когда разработчик заметит эту ошибку в процессе тестирования. А если же нет? В обоих случаях придется лезть в код и производить дебаг. Это лишнее время и лишние действия. Было бы круто, если компилятор умел видеть и такие ошибки, ведь:

А как компилятор должен определять "правильное" значение? Ведь значением по умолчанию не обязательно "0" может быть.

Pa4enka
22.01.2020, 21:30
А как компилятор должен определять "правильное" значение? Ведь значением по умолчанию не обязательно "0" может быть.

Здесь смысл не в 1/0, а в том что в одном блоке существует два присвоение одной и той же переменной. То есть, значение было ранее присвоено, но где-то ниже переопределено ещё раз(без всяких проверок и тд).

Daniel_Cortez
25.01.2020, 00:51
Интересно, а возможно ли расширить функционал компилятора до возможности определять повторяющиеся присвоения переменной в определенном блоке кода? Данное предложения похоже на warning 210 (https://pro-pawn.ru/showthread.php?16839-warning-210-%28-%29), ибо так же анализирует код с его логической стороны.
Не только можно, но и я его уже реализовал ещё осенью прошлого года (и, к слову о warning 210, многие куски кода таки были позаимствованы оттуда), просто дело так и не дошло до PR, да и не уверен, есть ли вообще смысл что-то предлагать сейчас разработчикам компилятора, если они до сих пор не решаются принять warning 210, и при этом не могут дать вразумительного аргумента против этой фичи (ИМХО, "инициализация нулём по умолчанию хорошо определена" - очень сомнительный аргумент, т.к. этому в официальной документации (Pawn Language Guide) посвящено всего одно предложение (которое дословно так и переводится "все переменные по умолчанию равны нулю"), без какого-либо объяснения, чем оправдана такая логика и чем это лучше предупреждений о неинициализированных переменных).

Касаемо самой проблемы, я так понимаю, можно упростить пример до

main()
{
new x = 0;
x = 1; // warning 240: previously assigned value is unused
return x;
}

На днях, как будет время (может быть даже на этих выходных), попробую сделать PR с этой фичей, а заодно и issue по switch-выражениям.




А как компилятор должен определять "правильное" значение? Ведь значением по умолчанию не обязательно "0" может быть.
Эм... никак? Ибо компилятор не может знать о контексте применения кода, это задача пользователя.

Pa4enka
25.01.2020, 01:07
На днях, как будет время (может быть даже на этих выходных), попробую сделать PR
Nice job ;)

Будем надеяться, что разработчики таки примут предложение от юзеров и внесут изменение в компилятор. А если же этого не случится - будем использовать твой вариант на постоянной основе.

И да, я думаю комьюнити оценит любые доработки. Тем более, мы не платим за его использование и имеем право выбора. А экспериментировать и обсуждать никто не запрещал)

DeimoS
25.01.2020, 12:24
Эм... никак? Ибо компилятор не может знать о контексте применения кода, это задача пользователя.

Я, собственно, о том и хотел сказать :) Хотел так же про "warning 240" от тебя написать и описать все "подводные камни", которые мы обсуждали, но решил, что ты сам напишешь о нём, если вдруг решишь ответить.

tnc
25.01.2020, 17:09
@Daniel_Cortez, не планируешь в своем форке сделать инициализацию "саб-массивов" через прогрессию? (...)


new array_3d[5][3][3] =
{
{
{1, 2, 3},
{4, 5, ...},
...
},
{
{1, 2, 3},
...
},
...
};


main()
{
for (new i = 0; i < sizeof(array_3d); i++)
{
for (new j = 0; j < sizeof(array_3d[]); j++)
{
for (new g = 0; g < sizeof(array_3d[][]); g++)
{
printf("array_value: %d", array_3d[i][j][g]);
}
}
}
}


Сейчас это выдает ошибку при компиляции:

error 001: expected token: "{", but found "..."
error 001: expected token: "}", but found ";"

Daniel_Cortez
31.01.2020, 17:20
@Daniel_Cortez, не планируешь в своем форке сделать инициализацию "саб-массивов" через прогрессию?
Во-первых, нет, не планирую, ибо понятия не имею, как работает тот спагетти-код для инициализации массивов.
Во-вторых, нет никакого "моего форка", была только пара-тройка неофициальных релизов с исправленными багами. Даже если бы я и захотел создать свой форк, была бы проблема с тем, как отличить его от форка Zeex'а - в последнем есть константы "__Pawn" и "__PawnBuild", но мне пришлось бы вводить свои константы и свою нумерацию версий, чтобы избежать "пересечений" с тем форком, не говоря уже о том, чтобы убедить скриптеров по всему миру переписать свои скрипты с учётом этих новых констант (в то время, как ещё со стокового компилятора 3.2.3664 не все хотят слезать).


Хотел так же про "warning 240" от тебя написать и описать все "подводные камни", которые мы обсуждали, но решил, что ты сам напишешь о нём, если вдруг решишь ответить.
Не припоминаю, чтобы мы обсуждали какие-то "подводные камни" по warning 240. Разве что единственный недостаток, что моя реализация пока что обнаруживает неиспользуемые присвоения только к одиночным переменных. Для массивов потребовалось бы гораздо больше изменений как в структурах хранения данных, так и в логике компилятора.

Как бы то ни было, пока что я оставлю реализацию как есть, т.е. только для одиночных переменных. Если примут её в таком виде, то тогда и только тогда будет смысл пытаться что-то химичить с массивами, иначе это будет просто пустая трата времени.

tnc
01.02.2020, 17:30
А что конкретно не понятно? Да это усложняет чтение кода, но это было бы круто, если бы была такая возможность инициализации массивов. Это идею предлагал и @ziggi (https://github.com/pawn-lang/compiler/issues/167)

ибо понятия не имею, как работает тот спагетти-код для инициализации массивов.

Daniel_Cortez
08.02.2020, 22:13
Вышла новая версия 3.10.10.

Скачать: https://github.com/Zeex/pawn/releases/tag/v3.10.10

Примечание: Начиная с данной версии требуется использовать модифицированные инклуды SA-MP, иначе у вас появится куча новых warning 239 (т.к. в стандартных инклудах не исправлена проблема с const-корректностью). Просто скачайте их по этой ссылке (click) (https://github.com/sampctl/samp-stdlib/archive/0.3.7-R2-1-1.zip) и скопируйте инклуды из архива в папку "pawno/include".

Изменения:
Добавлены новые директивы #pragma unread и #pragma unwritten, которые позволяют подавить предупреждения о том, что значение символа (переменной/константы/функции) нигде не считывается или не изменяется соответственно.
Принцип работы этих директив схож с уже существующей #pragma unused, однако позволяют подавлять отдельно только предупреждения о том, что значение символа не считывается, и отдельно, что не изменяется, тем самым лучше показывая намерения скриптера.

Добавлена директива #pragma nodestruct, которая инструктирует компилятор не вызывать деструктор при уничтожении локальной переменной.
Примечание (DC): Да, оказывается, в Pawn для переменных с любым тегом, кроме "_", можно создать деструктор - функцию, которая автоматически вызывается по окончании существования локальных переменных с заданным тегом.

Исправлен выход за пределы массива в коде упаковки данных (функция encode_cell()), который в редких случаях мог спровоцировать отключение сжатия файла *.amx с выводом сообщения "warning 232: output file is written, but with compact encoding disabled".

Добавлен оператор __addressof (#445 (https://github.com/pawn-lang/compiler/pull/445)).

Препроцессорный листинг (файл *.lst) теперь записывается после второго прохода препроцессора, т.е. именно в таком виде, в каком код в дальнейшем компилируется.

Обеспечено игнорирование неизвестных препроцессорных директив внутри #if/endif (#427 (https://github.com/pawn-lang/compiler/pull/427)).

Серия исправлений и улучшений, связанных с оператором __emit:

Добавлены псевдо-опкоды, которые можно использовать в макросах с операндами любого типа:

load.u.pri/alt - загрузить значение операнда (может быть выражением) в PRI/ALT.
stor.u.pri/alt - сохранить значение PRI/ALT в операнд.
addr.u.pri/alt - загрузить адрес операнда в PRI/ALT.
push.u - сохранить значение (может быть выражением) в стек.
push.adr.u - сохранить адрес операнда в стек.
zero.u - обнулить операнд.
inc.u/dec.u - увеличить/уменьшить значение операнда на 1.

Пример использования:

#define getval(%0) __emit(load.u.pri %0)
#define addrof(%0) __emit(addr.u.pri %0)

const global_const = 0x1234;
new global_var = 0x5678;

main()
{
const local_const = 0x4321;
new local_var = 0x8765;
static local_static_var = 0x9ABC;
static local_static_array[2];

printf("%08x", getval(global_const)); // 00001234
printf("%08x", getval(global_var)); // 00005678
printf("%08x", getval(local_const)); // 00004321
printf("%08x", getval(local_var)); // 00008765
printf("%08x", getval(local_static_var + global_const)); // 0000ACF0
printf("%08x", addrof(global_var)); // 00000000
printf("%08x", addrof(local_var)); // 00004094
printf("%08x", addrof(local_static_var)); // 00000004
printf("%08x", addrof(local_static_array[1])); // 0000000C
}

Компилятор теперь выдаёт ошибку, если смещение в стеке или адрес данных не кратен размеру ячейки (т.е. 4 байтам).

__emit load.s.pri 5; // error 011: stack offset/data address must be a multiple of cell size

Устранено падение, возникавшее когда с помощью __emit вызывается нативная функция, которая ранее ещё нигде не вызывалась.

Удалена проверка значений операндов (индексов) для инструкций lctrl и sctrl.

Опкоды stor.s.pri/alt, inc.s, dec.s, и zero.s больше не принимают аргументы функций, переданные по ссылке.

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

Исправлено множество случаев, когда при несоответствии типов аргументов в сообщениях об ошибках выводились неправильные названия типов.

Удалёно ключевое слово emit, оставлено только __emit (для соответствия новому правилу, согласно которому новые операторы должны начинаться с "__").


Исправлено падение компилятора, происходившее при использовании #error и #warning без указания текста ошибки/предупреждения.

Исправлено падение компилятора, когда после #pragma option параметр был длиннее 31 символа.

Исправлен неправильный вывод названия массива, когда оператор sizeof использовался на массиве неопределённого размера.

Func(const arr[])
{
// До исправления: warning 224: indeterminate array size in "sizeof" expression (symbol "")
// После: warning 224: indeterminate array size in "sizeof" expression (symbol "arr")
return sizeof(arr);
}

Исправлены ложные предупреждения о const-корректности (warning 239) в функциях, имеющих несколько реализаций для разных состояний автоматонов (state).

Исправлен баг, из-за которого компилятор при опечатке предлагал переменную до того, как она была реализована (#374 (https://github.com/pawn-lang/compiler/pull/374)).

GetValue()
{
return value; // error 017: undefined symbol "value"; did you mean "value"?
// Очевидно, что переменная "value" не должна быть видна отсюда, т.к. она объявлена только ниже.
}

new value = 0;

main()
{
GetValue();
}

Исправлен баг, из-за которого компилятор при опечатке не предлагал функцию, если ошибка допущена перед реализацией функции (#397 (https://github.com/pawn-lang/compiler/pull/397)).

main()
{
// Здесь компилятор должен предложить функцию "DoNothing", но он этого не делает,
// хоть в Pawn функции и могут вызываться до своего объявления и реализации.
DoNothin(); // error 017: undefined symbol "DoNothin"
}

DoNothing(){}


Устранено падение компилятора из-за попытке при опечатки предложить переменную с пустым названием (#451 (https://github.com/pawn-lang/compiler/issues/451)).

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

new var <state_a>;

main()
{
// До исправления: test.pwn(5) : error 017: undefined symbol "var"; did you mean "var"?
// После: test.pwn(5) : error 017: undefined symbol "var"; state variable out of scope
var = 5;
}

Исправлено некорректное сообщение об ошибке, выдаваемое, когда функции, принимающей массив, передаётся ячейка массива, переданного из другой функции по ссылке.

Func2(const arr[3])
{
return arr[0];
}

Func1(const arr[])
{
// До исправления: error 007: operator cannot be redefined
// После: error 047: array sizes do not match, or destination array is too small
Func2(arr[0]);
}

main()
{
static const arr[1];
Func1(arr);
}

Исправлена некорректная фатальная ошибка (error 106), выдаваемая, когда компактное кодирование (LEB128) файла *.amx неэффективно и разница между сжатыми и несжатыми данными составляет меньше 63 байт (вместо ошибки компилятор должен выдавать только предупреждение, что компактное кодирование оказалось невыгодно и файл записан несжатым (warning 232)).

main()
{
// Примечание: При компактном кодировании '0xAABBCCDD' плохо сжимается
// и занимает 5 байт вместо 4, тем самым делая сжатие неэффективным.
static const a[32] = { 0xAABBCCDD, ... };
return a[0];
// До исправления: fatal error 106: compiled script exceeds the maximum memory size (1521262808 bytes)
// После: warning 232: output file is written, but with compact encoding disabled
}

Исправлена фатальная ошибка, возникавшая при компиляции кода, в котором используется хотя бы одна из встроенных строковых констант (__file, __date, __time) и есть хотя бы одна функция, имеющая состояния.

#include <a_samp>

public OnGameModeInit()<automaton1:STATE1>{}

main()
{
// /home/travis/build/Zeex/pawn/source/compiler/sc4.c:76: writeleader: Assertion `glb_declared==0' failed.
printf("File: %s", __file);
}

Баг не проявлялся под Windows, однако ему были подвержены релизы компилятора для Linux и OS X.

Исправлен баг с возможностью для локальных переменных инициализироваться самими собой.

main()
{
// До исправления: нет сообщения об ошибках
// После: error 017: undefined symbol "test"
new test = test;
}

Что интересно, до исправления компилятор не выдавал даже предупреждения о том, что переменная в данном примере никак не использоована. Это связано с тем, что при такой инициализации компилятор засчитывал и чтение, и запись в переменную, и потому считал, что она полноценно используется.


Исправлен баг с игнорированием тегов в анонимных enum.

enum // Название не указано, тег тоже (следовательно,
{ // все константы внутри enum будут с тегом "_")
Float:DRAW_DISTANCE = 100.0
// ДО ИСПРАВЛЕНИЯ: код скомпилируется, но компилятор молча проигнорирует тег "Float:",
// и если кто-то попытается использовать эту константу, то вместо вещественного "100.0"
// получит целочисленное "_:100.0" (т.е. "1120403456", ибо приведение тега - это не конверсия).
// ПОСЛЕ ИСПРАВЛЕНИЯ: error 001: expected token: "-identifier-", but found "-label-"
};

Daniel_Cortez
08.02.2020, 22:20
(Если вы ещё не видели, выше пост с релизом компилятора 3.10.10).

От себя добавлю, что процесс работы над компилятором всё ещё оставляет желать лучшего:
Мейнтейнеры подготовили релиз только после того, как я вчера "как бы невзначай" напомнил (https://github.com/pawn-lang/compiler/issues/482#issuecomment-583452376) им, что прошло уже полтора года и, может быть, пора бы уже что-нибудь выкатить. (Я мог бы и раньше это сделать, создав отдельный issue, но это, как минимум, выглядело бы некрасиво.)
Куча PR'ов, находящихся в очереди (https://github.com/pawn-lang/compiler/pulls) на принятие, были попросту проигнорированы перед релизом - включая даже те из них, которые уже были рассмотрены и одобрены.


В ближайшее время попробую подготовить неофициальный билд с теми PR'ами, которые не расширяют сам язык Pawn и не ломают совместимость.

SteveStage
09.02.2020, 00:14
Исправлен баг с игнорированием тегов в анонимных enum.

enum // Название не указано, тег тоже (следовательно,
{ // все константы внутри enum будут с тегом "_")
Float:DRAW_DISTANCE = 100.0
// ДО ИСПРАВЛЕНИЯ: код скомпилируется, но компилятор молча проигнорирует тег "Float:",
// и если кто-то попытается использовать эту константу, то вместо вещественного "100.0"
// получит целочисленное "_:100.0" (т.е. "1120403456", ибо приведение тега - это не конверсия).
// ПОСЛЕ ИСПРАВЛЕНИЯ: error 001: expected token: "-identifier-", but found "-label-"
};



Объяснишь поконкретнее?) Т.е. теперь тэг энума (_:) не распространяется на его составляющие? Или что имелось ввиду?

execution
09.02.2020, 10:29
Объяснишь поконкретнее?) Т.е. теперь тэг энума (_:) не распространяется на его составляющие? Или что имелось ввиду?

То есть теперь выдаст ошибку:

error 001: expected token: "-identifier-", but found "-label-"

SteveStage
09.02.2020, 13:14
То есть теперь выдаст ошибку:

error 001: expected token: "-identifier-", but found "-label-"

Да я это понял. А что с использованием анонимных энумов - их теперь нельзя использовать или как?

execution
09.02.2020, 13:39
Да я это понял. А что с использованием анонимных энумов - их теперь нельзя использовать или как?

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

SteveStage
09.02.2020, 13:57
Где ты увидел, что их использовать нельзя и т.п.?
Если ты будешь использовать в анонимных перечислителях константы с тэгами, то выдаст ошибку.

Я понял тебя) Т.е. в энуме константы идут в порядке возрастания, а с разными тэгами возрастание невозможно (например сначала идет константа с тэгом Float: и со значение 1.2, а потом пустая с тэгом _:, и по сути константа-переменная должна хранить 2.2, но переменные не могут хранить плавающие значения).

Daniel_Cortez
11.02.2020, 21:15
Забыл упомянуть в предыдущем посте с релизом: начиная с версии 3.10.10 требуется использовать модифицированные инклуды SA-MP (https://github.com/sampctl/samp-stdlib) (со стандартными будет куча новых warning 239 при использовании функций SA-MP, т.к. в них не исправлены проблемы с const-корректностью).
Для этого перейдите по этой ссылке (https://github.com/sampctl/samp-stdlib), в правом верхнем углу нажмите зелёную кнопку "Clone or download", затем в открывшемся меню "Download ZIP", после чего из скачавшегося ZIP-архива скопируйте инклуды в папку "pawno/include".


Тем временем, как и было обещано, я подготовил неофициальный билд, в который добавил пару-тройку фич, которые почему-то не были рассмотрены перед подготовкой релиза 3.10.10.

Изменения (в сравнении с официальным билдом 3.10.10):
Добавлена диагностика для обнаружения использования неинициализированных переменных (warning 210 (https://pro-pawn.ru/showthread.php?16839-warning-210)).
Устранён недочёт с отсутствием проверки на несовпадение тегов между выражениями в switch и case.
(NEW) Добавлены/улучшены диагностики для обнаружения неиспользуемых присвоений к переменным:
Улучшена работа warning 204 (выдаётся, когда переменной присвоено значение, но оно не используется), теперь она работает в большем количестве случаев.
Пример работы:

main()
{
new n = 1;
printf("%d", n);

// Присвоим переменной "n" новое значение, но оставим его неиспользованным.
// По идее это лишний код, но раньше компилятор не замечал его (потому что
// переменная была использована в 'printf()'), теперь же он выдаёт предупреждение.
n = 2; // warning 204: symbol is assigned a value that is never used: "n"
}

Добавлена диагностика warning 240 (предыдущее значение, присвоенное к переменной, не было использовано).
Пример работы:

main()
{
new n = 1;

// Присвоим переменной новое значение, при этом прежнее ("1") не будет использовано.
// Это тоже лишний код, но не совсем такой, как в warning 204 (т.к. неиспользованным
// остаётся не текущее значение переменной, а предыдущее), потому новый warning.
n = 2; // warning 240: previously assigned value is never used (symbol "x")
printf("%d", n);
}



Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

Pa4enka
12.02.2020, 02:33
...
Либо твой форк немного сыроват, либо мои руки не готовы к нему :)

warning 240: previously assigned value is never used (symbol "tmpobjid")
Выдает на все строки кода маппинга, где tmpobjid = CreateDynamicObject. Логика компилятора понятна, но, увы, ложная. Ибо даже убрав "tmpobjid =", компилятор все еще видит ошибку. Маппинг - pastebin (https://pastebin.com/QKtU4Wz9)(в этом варианте я убрал лишние присвоения, но компилятор все равно орет)

Компилятор так же сообщил мне, что существуют ошибки в инклудах YSI:

YSI_Storage\..\YSI_Internal\..\amx\codescan.inc(764) : warning 213: tag mismatch: expected tag "bool", but found none ("_")
YSI_Storage\..\YSI_Internal\..\amx\codescan.inc(770) : warning 213: tag mismatch: expected tag "bool", but found none ("_")
YSI_Storage\y_amx.inc(997) : warning 210: possible use of symbol before initialization: "idx"
YSI_Storage\y_amx.inc(1032) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(299) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(359) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(550) : warning 210: possible use of symbol before initialization: "count"
YSI_Coding\y_hooks/impl.inc(591) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(1050) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(1140) : warning 210: possible use of symbol before initialization: "idx"

Предполагаю, что версия библиотеки устарела, ибо временно компилирую без sampctl, но этот вариант чуть позже проверю.

tnc
12.02.2020, 13:28
Блин, а почему #pragma once (https://github.com/pawn-lang/compiler/pull/463)не приняли? Есть на это какие-то причины?

Daniel_Cortez
12.02.2020, 20:49
Либо твой форк немного сыроват, либо мои руки не готовы к нему :)

warning 240: previously assigned value is never used (symbol "tmpobjid")
Выдает на все строки кода маппинга, где tmpobjid = CreateDynamicObject. Логика компилятора понятна, но, увы, ложная. Ибо даже убрав "tmpobjid =", компилятор все еще видит ошибку. Маппинг - pastebin (https://pastebin.com/QKtU4Wz9)(в этом варианте я убрал лишние присвоения, но компилятор все равно орет)


Пробовал скомпилировать вот так:

#include <a_samp>
#include <streamer>
#include <YSI_Coding\y_hooks>

hook OnGameModeInit()
{
new
tmpobjid,
map_world = 0, map_int = 0;

tmpobjid = CreateDynamicObject(19366, 1755.166015, -1898.626953, 12.501999, 0.000000, 90.000000, 0.000000, map_world, map_int, -1, 200.00, 200.00);
SetDynamicObjectMaterial(tmpobjid, 0, 10101, "2notherbuildsfe", "Bow_church_grass_alt", 0x00000000);

// всё остальное, что было в листинге на pastebin

return Y_HOOKS_CONTINUE_RETURN_1;
}

Ни на 4-й, ни на 5-й версии YSI не было никаких варнингов касаемо tmpobjid. Я что-то делаю не так?


Компилятор так же сообщил мне, что существуют ошибки в инклудах YSI:

YSI_Storage\..\YSI_Internal\..\amx\codescan.inc(764) : warning 213: tag mismatch: expected tag "bool", but found none ("_")
YSI_Storage\..\YSI_Internal\..\amx\codescan.inc(770) : warning 213: tag mismatch: expected tag "bool", but found none ("_")
YSI_Storage\y_amx.inc(997) : warning 210: possible use of symbol before initialization: "idx"
YSI_Storage\y_amx.inc(1032) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(299) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(359) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(550) : warning 210: possible use of symbol before initialization: "count"
YSI_Coding\y_hooks/impl.inc(591) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(1050) : warning 210: possible use of symbol before initialization: "idx"
YSI_Coding\y_hooks/impl.inc(1140) : warning 210: possible use of symbol before initialization: "idx"

Предполагаю, что версия библиотеки устарела, ибо временно компилирую без sampctl, но этот вариант чуть позже проверю.
Насчёт варнингов в YSI - давно известная проблема, ибо там во многих местах используют "new idx;" вместо "new idx = 0;". По-хорошему, есть смысл исправить это в самой библиотеке, но я ей не пользуюсь, и поэтому не могу знать обо всех местах, где выдаётся warning 210.
Пока что в качестве обходного пути могу только предложить временно отключить варнинг перед подключением инклудов из YSI (в теме про warning 210 (https://pro-pawn.ru/showthread.php?16839-warning-210) написано, как это сделать).
И да, на счёт варнингов в codescan.inc интересно, я не смог их воспроизвести у себя. Можешь где-нибудь выложить ту версию инклуда, которая у тебя (он должен быть в папке "amx_assembly")?

Pa4enka
12.02.2020, 23:14
...

На маппинг компилятор ругался из-за того, что файл был продублирован в нескольких местах. Хотя я вчера и сверял путь несколько раз , но видимо из-за усталости не заметил отличий. В общем, ложная тревога, извини.

YSI апдейтнул до последней версии с официального гитхаба и те ошибки с несовпадением тегов пропали, но как только я возвращаю обратно старую версию - варнинги появляются.

Посмотреть файл (https://www.dropbox.com/s/opu1r6kd5zbocbo/codescan.inc?dl=0)
Ругается на switch внутри функции "CodeScanRun", конкретно "case -1" и "case 0".
Файл находится в папке "amx".
Версия YSI: 4.0.0 либо 4.0.1

tnc
16.04.2020, 06:19
Вот так вот выдает warning 213. Это баг?

#if !defined MAX_TEST_TEXT_DRAW
const MAX_TEST_TEXT_DRAW = 64;
#endif

enum
{
ITEM_FIRST,
ITEM_SECOND
}

new Text: g_test_textdraw[MAX_TEST_TEXT_DRAW];

main()
{
g_test_textdraw[ITEM_FIRST] = TextDrawCreate(0.0, 0.0, "Warning 213 test!");
}


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


#if !defined MAX_TEST_TEXT_DRAW
const MAX_TEST_TEXT_DRAW = 64;
#endif

enum
{
ITEM_FIRST,
ITEM_SECOND
}

new Text: g_test_textdraw[MAX_TEST_TEXT_DRAW];

main()
{
printf("g_test_textdraw[%d]: %d",
ITEM_FIRST,
g_test_textdraw[ITEM_FIRST]
);
}


P.S: Pawn compiler 3.10.10

Daniel_Cortez
16.04.2020, 21:13
...
Спасибо, что сообщили, и да, похоже на баг. Проявляется в версиях 3.10.1 - 3.10.10, отсутствует в 3.2.3664.

const TD_0 = 0;
enum { TD_1 = 1 };
new Text: textdraws[10];

main()
{
textdraws[TD_0] = TextDrawCreate(0.0, 0.0, "-"); // на этой строке нет никаких предупреждений/ошибок
textdraws[TD_1] = TextDrawCreate(0.0, 0.0, "-"); // warning 213: tag mismatch: expected tag none ("_"), but found "Text"
}

Судя по всему, проблема в том, что если в качестве индекса для ячейки массива используется элемент перечисления (вместо обычной константы, объявленной с помощью ключевого слова const), то тег такого элемента "перезаписывает" тег массива, из-за чего компилятор думает, что у ячейки массива тег "_:", а не "Text:".
В принципе такая перезапись тега может быть использована, когда элемент перечисления принадлежит именованному массиву:

enum ePlayerInfo
{
Float:pHealth
};
new player_info[MAX_PLAYERS][ePlayerInfo];
// ...
// `player_info` имеет тег `_:` (т.е. без тега), но результирующий тег
// перезаписывается тегом из `pHealth`
player_info[playerid][pHealth] = 100.0;

что абсолютно логично, но соль в том, что, оказывается, это правило почему-то распространяется и на элементы анонимных перечислений (т.е. как в первом примере), чего по идее быть не должно, и таки этого нет в стоковом 3.2.3664.
Пока что я создал issue на GitHub: https://github.com/pawn-lang/compiler/issues/514
Исправление должно быть очень простым (достаточно добавить всего одну проверку, чтобы результирующий тег перезаписывался только если элемент перечисления принадлежит к именованному enum), но пока что желательно дождаться ответа от разработчиков; возможно, Y_Less что-нибудь возразит.

Salik_Davince
19.04.2020, 16:33
Кстати можно вопрос, где можно увидеть списки параметров для компилятора?

Вот у меня в моде некоторые функции используются до их объявления (прим.) -

function PlayerConnect(playerid) {
checkBan(playerid);
}

stock checkBan(playerid) {
code...
}


Знаю так кодить плохо, и компилятор выдаёт ошибку, но как разрешить такое через параметры или как можно вообще сделать такое?


---EDIT


Исправлен баг, из-за которого компилятор при опечатке не предлагал функцию, если ошибка допущена перед реализацией функции (#397).
main()
{
// Здесь компилятор должен предложить функцию "DoNothing", но он этого не делает,
// хоть в Pawn функции и могут вызываться до своего объявления и реализации.
DoNothin(); // error 017: undefined symbol "DoNothin"
}

DoNothing(){}


Вроде-бы должно было исправиться, да? Но скачал-поставил, то же самая проблема.

Daniel_Cortez
20.04.2020, 18:24
Кстати можно вопрос, где можно увидеть списки параметров для компилятора?
Открыть командную строку и в ней запустить pawncc без параметров - компилятор перечислит все возможные параметры и их описание (правда, на английском; возможно, кто-то раньше и делал перевод на русский язык, но я таких не припоминаю, за исключением одной совместной с Tracker1 работы (https://pro-pawn.ru/showthread.php?3586), которая безнадёжно устарела).



Знаю так кодить плохо, и компилятор выдаёт ошибку, но как разрешить такое
Не понимаю, о чём вы. В Pawn из коробки поддерживается использование функций до их объявления. Разве что компилятор может выдать предупреждение, если такая функция имеет тег (пример: функция возвращает здоровье игрока, т.е. значение с тегом "Float:"), но ошибок по идее быть не должно. Если компилятор выдаёт ошибку, дело может быть в макросах, которые "притворяются" функциями - их как раз нельзя использовать до объявления.



Вроде-бы должно было исправиться, да? Но скачал-поставил, то же самая проблема.
С каким кодом проявляется такая проблема? Я это должен за вас угадывать?

Salik_Davince
25.04.2020, 11:03
В Pawn из коробки поддерживается использование функций до их объявления.

В данном случае что-то идёт не так, я ставил опции, -Z+, -Z, прагму - #pragma compat 1
Но ошибки похожи на те что ниже ссылкой, точно такие же, только практически везде

https://github.com/pawn-lang/compiler/pull/397

Такой же баг, ошибки 017 // error 017: undefined symbol "abs... (функции)"

И так практически по всем функциям, (stock, некоторые паблики), могу выдать мод для проверки, поймете о чем я.

Salik_Davince
11.05.2020, 00:53
Странно, является ли это багом компилятора? Либо что-то я сделал не так.

Создал enum


enum pTemp
{
tempID,
tempName[MAX_PLAYER_NAME],
tempGun[2]
};

new PlayerTemp[MAX_PLAYERS][pTemp];


То если я внутри свитча (switch)'a присваиваю название переменной PlayerTemp (tempName) через скобки другое название игроку (прим.) -


switch(params)
{
case 1: PlayerTemp[playerid][tempName] = "Неизвестный";//(error 047: array sizes do not match, or destination array is too small)
case 2: PlayerTemp[playerid][tempName] = "Известный";//(error 047: array sizes do not match, or destination array is too small)
}


То идет варнинг (error 047: array sizes do not match, or destination array is too small) -

При логировании через printf - tempName пустая -

printf("PlayerTemp[playerid][tempName] = %s", PlayerTemp[playerid][tempName]);//PlayerTemp[playerid][tempName] =



-------------


Но если это сделать через format - то все отлично (прим) -


format(PlayerTemp[playerid][tempName], MAX_PLAYER_NAME, "Неизвестный");


Никаких ошибок, через логирование printf'a выводит что PlayerTemp[playerid][tempName] = Неизвестный


printf("PlayerTemp[playerid][tempName] = %s", PlayerTemp[playerid][tempName]);//PlayerTemp[playerid][tempName] = Неизвестный

SteveStage
11.05.2020, 12:59
Странно, является ли это багом компилятора? Либо что-то я сделал не так.

Создал enum


enum pTemp
{
tempID,
tempName[MAX_PLAYER_NAME],
tempGun[2]
};

new PlayerTemp[MAX_PLAYERS][pTemp];


То если я внутри свитча (switch)'a присваиваю название переменной PlayerTemp (tempName) через скобки другое название игроку (прим.) -


switch(params)
{
case 1: PlayerTemp[playerid][tempName] = "Неизвестный";//(error 047: array sizes do not match, or destination array is too small)
case 2: PlayerTemp[playerid][tempName] = "Известный";//(error 047: array sizes do not match, or destination array is too small)
}


То идет варнинг (error 047: array sizes do not match, or destination array is too small) -

При логировании через printf - tempName пустая -

printf("PlayerTemp[playerid][tempName] = %s", PlayerTemp[playerid][tempName]);//PlayerTemp[playerid][tempName] =



-------------


Но если это сделать через format - то все отлично (прим) -


format(PlayerTemp[playerid][tempName], MAX_PLAYER_NAME, "Неизвестный");


Никаких ошибок, через логирование printf'a выводит что PlayerTemp[playerid][tempName] = Неизвестный


printf("PlayerTemp[playerid][tempName] = %s", PlayerTemp[playerid][tempName]);//PlayerTemp[playerid][tempName] = Неизвестный


Ты сейчас конечно бред сказал. Ты не можешь переуказать содержимое массива после его создания, только форматировать, так всегда в pawn было.

tnc
11.05.2020, 17:22
Ты сейчас конечно бред сказал. Ты не можешь переуказать содержимое массива после его создания, только форматировать, так всегда в pawn было.

Вообще можно через = приравнивать строки, если размер строк равен.

ТС:



enum pTemp
{
tempID,
tempName[MAX_PLAYER_NAME + 1],
tempGun[2]
};

new PlayerTemp[MAX_PLAYERS][pTemp];

main()
{
static const name[][MAX_PLAYER_NAME + 1] =
{
"Неизвестный",
"Известный"
};
PlayerTemp[0][tempName] = name[0];
}

Daniel_Cortez
11.05.2020, 21:22
Вообще можно через = приравнивать строки, если размер строк равен.
Наверное, всё-таки, не "приравнивать", а "присваивать"? И да, присвоение возможно не только если размер массива-приёмника равен, но ещё и если он больше размера присваиваемого значения.



Создал enum


enum pTemp
{
tempID,
tempName[MAX_PLAYER_NAME],
tempGun[2]
};

new PlayerTemp[MAX_PLAYERS][pTemp];


То если я внутри свитча (switch)'a присваиваю название переменной PlayerTemp (tempName) через скобки другое название игроку (прим.) -


switch(params)
{
case 1: PlayerTemp[playerid][tempName] = "Неизвестный";//(error 047: array sizes do not match, or destination array is too small)
case 2: PlayerTemp[playerid][tempName] = "Известный";//(error 047: array sizes do not match, or destination array is too small)
}


То идет варнинг (error 047: array sizes do not match, or destination array is too small)
Компилятор всё делает правильно. Соль в том, что PlayerTemp[playerid][tempName] - это не массив, а только ячейка массива.
enum - это не аналог struct из C/C++, это обычный оператор для перечислений, возможности которого были немного расширены по сравнению с enum в тех же C и C++.
Т.е., такое перечисление:

enum
{
eFieldA[10],
eFieldB
};

и такое:

enum
{
eFieldA,
eFieldB = eFieldA + 10
};

- это абсолютно одно и то же, только записанное разными способами. Именно поэтому в цитате выше компилятор не позволяет присвоить строковый литерал в tempName - нельзя присвоить массив в одиночную ячейку массива.

arcttic
12.05.2020, 02:12
static ac_KickWithCode(playerid, ip_address[], type, code, code2 = 0)

Связан с античитом, никто не сталкивался с подобным?

Daniel_Cortez
12.05.2020, 15:41
static ac_KickWithCode(playerid, ip_address[], type, code, code2 = 0)

Связан с античитом, никто не сталкивался с подобным?
Что это такое и как это связано с темой обсуждения (компилятор)?

arcttic
12.05.2020, 15:53
Что это такое и как это связано с темой обсуждения (компилятор)?

Связан с варнингом const корректности


warning 239: literal array/string passed to a non-const parameter

tnc
12.05.2020, 18:08
Связан с варнингом const корректности


warning 239: literal array/string passed to a non-const parameter

Ну так поправьте.

arcttic
13.05.2020, 03:17
Ну так поправьте.

Я и обратился вопросом по данной версии компилятора, хотел бы узнать, что можно сделать...

Fallen A.
13.05.2020, 11:15
Всегда присваивал значение ячейке массива с помощью встроенной функции, если это касалось string значения. Что не так я делаю?

Daniel_Cortez
13.05.2020, 14:17
https://pro-pawn.ru/showthread.php?16434-const-%D0%BA%D0%BE%D1%80%D1%80%D0%B5%D0%BA%D1%82%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%28warning-239%29

Daniel_Cortez
30.06.2020, 22:41
"Неофициальный" релиз 3.10.10+ от 31.06.2020.

Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

В данном билде вы можете ознакомиться как с улучшениями для уже представленных ранее варнингов (204, 240), так и с новыми диагностиками, которые могут помочь в нахождении скрытых ошибок в вашем коде:
(FIX) Исправлен баг, из-за которого элементы перечислений при использовании в качестве индекса элемента массива замещали своим тегом тег ячейки массива (отдельное спасибо пользователю tnc (https://pro-pawn.ru/member.php?9450-tnc) за то, что сообщил (https://pro-pawn.ru/showthread.php?2207&p=96537&viewfull=1#post96537) об этом баге).

(FIX) Для варнингов 204 и 240 (неиспользуемые присвоения к переменным) реализован гораздо более изощрённый механизм отслеживания присвоений, благодаря чему компилятор теперь умеет находить неиспользуемый код в более сложных случаях.

(NEW) warning 241: negative or too big shift count - отрицательный или слишком большой счётчик битового сдвига.
Теперь если счётчик битового сдвига (2-й операнд в операциях "<<", ">>" и ">>>") отрицательный или больше 31, такая операция сдвига считается подозрительной, т.к. в ячейке всего 32 бита.
Эта диагностика может быть особенно полезна, если пользователь пытается уместить слишком много битовых флагов в одной переменной.

enum ePlayerFlags
{
pfEmailConfirmed, // 0
pfTutorialCompleted, // 1
/* ... */ // ...
pfImprisoned, // 31
pfHospitalized // 32, флаг не сохранится, т.к. при сдвиге на 32 позиции влево
// он окажется "вытолкнут" из ячейки (переполнение)
};

// ...

player_info[playerid][pFlags] |= (1 << pfHospitalized); // warning 24X: negative or too big shift count

(NEW) warning 242: shift overflow in enum item declaration (symbol "%s") - переполнение при левом сдвиге в объявлении одного из членов перечисления.
Тоже выявляет случаи, когда пользователь объявил слишком много битовых флагов, но только в самих перечислениях, если пользователь указал в качестве инкремента левый битовый сдвиг.

enum ePlayerFlags (<<= 1)
{
/* 1 << 0 */ pfEmailConfirmed = 1,
/* 1 << 1 */ pfTutorialCompleted,
/* ... */
/* 1 << 31 */ pfImprisoned,
/* 1 << 32 */ pfHospitalized // переполнение
};

В приведённом выше примере значение константы pfHospitalized на самом деле рассчитывается не как (1 << 32), а как (pfImprisoned << 1) (т.е. на основе значения предыдущего члена перечисления), поэтому в таком случае предупреждение о неправильном счётчике сдвига (warning 241) было бы неверным, т.к. у счётчика на самом деле правильное значение (1). Тем не менее, при расчёте значения константы происходит переполнение, поэтому для таких случаев и был сделан отдельный варнинг.

(NEW) warning 243: redundant code: switch control expression is constant - излишний код: контрольное выражение внутри switch является константным.
Подобные варнинги уже действуют при использовании константы или константного выражения в if, while, do-while и for ("redundant code: constant expression is zero", "redundant test: constant expression is non-zero"), поэтому логично иметь подобного рода диагностику и для switch.
На данный момент мне известно только об одном ложном срабатывании в инклудах amx_assembly, просьба о нём не сообщать! Насколько я понимаю, это особый случай нестандартного использования switch (самомодифицирующийся код?), и я предложу в репозиторий amx_assembly исправление, как только варнинг примут в состав компилятора.

(NEW) warning 244: enum item "%s" not handled in switch - для одного или нескольких членов перечисления не предусмотрен(ы) case внутри switch, а также нет ветки default.

enum EFamily
{
FAM_GROVE,
FAM_BALLAS,
FAM_VAGOS,
FAM_AZTECAS
};

stock GetFamilyColor(EFamily:family)
{
switch (family)
{
// ПРИМЕЧАНИЕ: пользователь забыл добавить case для FAM_AZTECAS
case FAM_GROVE: return COLOR_GREEN;
case FAM_BALLAS: return COLOR_PURPLE;
case FAM_VAGOS: return COLOR_YELLOW;
} // warning 244: enum item "FAM_AZTECAS" not handled in switch

return COLOR_GREY;
}



P.S.: Не стесняйтесь сообщать сюда о ложных срабатываниях варнингов, если таковые вдруг будут, либо же просто отписываться об интересных скрытых недочётах, которые вы смогли найти благодаря новым диагностикам, ибо лишняя аргументация за принятие варнингов в состав компилятора точно не помешает :)

DeimoS
02.07.2020, 19:03
Как минимум, 213-ое предупреждение для switch крайне полезным оказалось, так что советую всем с этим компилятором свои скрипты проверить.

Сейчас скинули мод вместе с заказом и там была система прикрепления объектов к скинам с разными координатами для разных ID. И было такое перечисление:

switch(skin)
{
/*прочие case*/
case 9,11,12,13,40.41,55,56,63,64,65,69,75,76,85,89,90,91,92,93,131,138,139,140,141,145.148,150,151,152,157,169,172,178,190,191,192,193,194,198,201,209,210,211,214,215,216,219,224.225,226,229,230,233,237,238,244,246,251,256,257,263,306,307,308,309: /*прикрепление объекта*/
/*прочие case*/
}
Собственно, обычный компилятор такой код пропустит без проблем. Но если внимательно присмотреться, в нескольких местех вместо запятой стоит точка.
switch(skin)
{
/*прочие case*/
case 9,11,12,13,40.41,55,56,63,64,65,69,75,76,85,89,90,91,92,93,131,138,139,140,141,145.148,150,151,152,157,169,172,178,190,191,192,193,194,198,201,209,210,211,214,215,216,219,224.225,226,229,230,233,237,238,244,246,251,256,257,263,306,307,308,309: /*прикрепление объекта*/
/*прочие case*/
}

Соответственно, ни о какой правильной работоспособности и речи тут не идёт. И глазом такую ошибку не с первого раза обнаружишь.

Daniel_Cortez
02.07.2020, 22:16
"Неофициальный" релиз 3.10.10+ от 02.07.2020 (hotfix).

В данном релизе исправлены ложные срабатывания варнингов 204 и 240, при которых выводились случайные (неправильные) номера строк, например:
pawno\include\functions.inc(758132272) : warning 204: symbol is assigned a value that is never used: "playerid"
Если с предыдущим билдом от 30.06.2020 (https://pro-pawn.ru/showthread.php?2207&p=96954&viewfull=1#post96954) у вас были подобные сообщения - крайне рекомендуется использовать этот билд.

Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

Полный список изменений (с момента предыдущего билда от 30.06.2020):

Исправлен баг с локальными константами, продолжающими существовать после окончания локального блока, внутри которого они были объявлены.

main()
{
if (/* ... */)
{
const CONSTVAL = 0;
}
return CONSTVAL; // Из-за бага такой код компилировался, хотя по идее константа CONSTVAL
// должна была перестать существовать после окончания блока "if".
}

Исправлены ложные срабатывания варнингов 204 и 240 в случаях, когда внутри if или switch объявлена локальная константа (отдельное спасибо DeimoS (https://pro-pawn.ru/member.php?2548-DeimoS)'у за то, что сообщил о проблеме).
Причиной оказался упомянутый пунктом выше баг с областью существования констант, из-за которого ломался алгоритм отслеживания присвоений.

nekaz
08.07.2020, 19:52
Кхм, использую последний релиз компилятора, получаю 239 варинг, при использовании диалога. Собственно скрин варинга - https://prnt.sc/te6t10
скрин диалога - https://prnt.sc/te6tp8

UPD: на все функции которые содержат "text[]" и т.д. получаем 239 вар, закрадываются сомнение в правильном работоспособности, ибо это ж дефолтные функции, теперь необходимо к каждой функции дописывать const.... :sad:

Daniel_Cortez
09.07.2020, 09:56
Кхм, использую последний релиз компилятора, получаю 239 варинг, при использовании диалога. Собственно скрин варинга - https://prnt.sc/te6t10
скрин диалога - https://prnt.sc/te6tp8

UPD: на все функции которые содержат "text[]" и т.д. получаем 239 вар, закрадываются сомнение в правильном работоспособности, ибо это ж дефолтные функции, теперь необходимо к каждой функции дописывать const.... :sad:
Начиная с версии 3.10.10 с компилятором требуется использовать модифицированные инклуды SA-MP (https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip), в которых исправлена проблема с const-корректностью и множество других недочётов.
Подробнее о const-корректности: https://pro-pawn.ru/showthread.php?16434

nekaz
09.07.2020, 11:38
Начиная с версии 3.10.10 с компилятором требуется использовать модифицированные инклуды SA-MP (https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip), в которых исправлена проблема с const-корректностью и множество других недочётов.
Подробнее о const-корректности: https://pro-pawn.ru/showthread.php?16434
Ага, все вопрос снят, спасибо.

tnc
13.07.2020, 18:45
@Daniel_Cortez, а этот баг до сих пор не исправлен?

https://github.com/pawn-lang/compiler/issues/181
https://github.com/pawn-lang/compiler/issues/350

Если нет, то возможно, что ты захочешь исправить в своей версии компилятора?

Daniel_Cortez
15.07.2020, 20:41
@Daniel_Cortez, а этот баг до сих пор не исправлен?

https://github.com/pawn-lang/compiler/issues/181
https://github.com/pawn-lang/compiler/issues/350

Если нет, то возможно, что ты захочешь исправить в своей версии компилятора?
Если вкратце, не углубляясь в суть бага, то придётся переписывать очень много кода (а именно - заставить компилятор хранить препроцессированные тексты в UTF-8 вместо того, чтобы переключаться между разными кодировками), и я сомневаюсь, что исправление вообще примут, судя по тому, как в репо компилятора до сих пор висят полтора десятка куда более простых PRов.

tnc
16.07.2020, 18:59
окей, если фикс не прокатит в upstream, то может быть стоит, хотя-бы сделать диагностику этого? Ибо на днях, я столкнулся с этой проблемой и потратил 5 минут, чтобы понять, почему перестал компилироваться мод. Я знал об этом баге, но что если новички, которые не знают об этом баге? Они потратят много времени, чтобы найти почему компилятор ушел в infinite loop (это новая версия от pawn-lang (https://github.com/pawn-lang), дефолтный компилятор 3.2 (который поставляется с сервером скорее всего вообще крашнит)

Daniel_Cortez
24.07.2020, 14:45
окей, если фикс не прокатит в upstream, то может быть стоит, хотя-бы сделать диагностику этого? Ибо на днях, я столкнулся с этой проблемой и потратил 5 минут, чтобы понять, почему перестал компилироваться мод. Я знал об этом баге, но что если новички, которые не знают об этом баге? Они потратят много времени, чтобы найти почему компилятор ушел в infinite loop (это новая версия от pawn-lang (https://github.com/pawn-lang), дефолтный компилятор 3.2 (который поставляется с сервером скорее всего вообще крашнит)
Во-первых, багу подвержены все версии компилятора, и последний релиз 3.10.10 может крашнуть примерно с такой же вероятностью, как и стоковый 3.2.3664.
Во-вторых, даже если и рассматривать вариант с диагностикой как временную меру, пока что я не уверен, как такую диагностику можно было бы реализовать в более-менее приемлемом виде. Если добавить её как простой варнинг, компилятор всё равно будет крашить; если же сделать её как fatal error - это предотвратит краш путём прерывания компиляции, но будет выглядеть избыточным ради одного бага.
В-третьих, есть куча других багов, которые нужно исправить, и фич, которые я хотел бы добавить к следующему релизу компилятора, и на всё это мне приходится тратить своё личное время. Именно поэтому пока что я занимаюсь теми багами, которые я знаю, как исправить, и фичами, которые я знаю, как реализовать. Касаемо бага с кодировками, возможно, получится исправить его позже (например, если вдруг удастся наткнуться на более-менее простое решение во время исправления другого бага - такое уже бывало, и не раз).

Daniel_Cortez
06.09.2020, 20:34
"Неофициальный" релиз 3.10.10+ от 06.09.2020.

Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip


Улучшены диагностики для обнаружения недостижимого кода ("warning 225: unreachable code").
Теперь компилятор умеет находить "мёртвый" код в следующих случаях:
Когда все case в switch (в том числе default) заканчиваются оператором "return", "break", "continue" или любым другим "завершающим" оператором:

switch (value)
{
case 0: return 0;
case 1..10: return 2;
default:
{
print("??");
return 3;
}
}
return 4; // warning 225: unreachable code


Когда разные ветви if заканчиваются разными видами "завершающих" операторов:

new x;
do {
if (x)
break;
else
continue;
x++; // warning 225: unreachable code
} while (x);

Раньше компилятор замечал недостижимый код только когда обе ветви if заканчивались одинаковыми операторами (например, обе на return).

После оператора goto, когда дальше нет никаких меток и можно точно определить, что дальнейший код никогда не выполнится:

label_1:
goto label_1;
return 0; // warning 225: unreachable code



Исправлен баг, из-за которого можно было совершать присвоения к константным многомерным массивам.

new const a[1][1];
a[0][0] = 0; // такой код компилировался без ошибок, несмотря на то,
// что массив должен быть неизменяемым ("const")

Отдельное спасибо DeimoS (https://pro-pawn.ru/member.php?2548-DeimoS)'у за то, что сообщил о данном баге.

Исправлен баг, связанный с возвратом массивов из функций напрямую.

ReturnString0()
{
return "abc";
}

ReturnString1()
{
// при повторном возврате массива, возвращённого напрямую из другой функции, генерировался
// неправильный байткод, приводящий к сбою (ошибке времени выполнения) на сервере
return ReturnString0();
}

Подробнее об этом баге можно узнать из статьи "Почему не следует возвращать строки/массивы напрямую" (https://pro-pawn.ru/showthread.php?16888).

Исправлен баг, из-за которого компилятор при использовании тернарного оператора на массивах не учитывал размер 3-го аргумента.

static const str1[] = "123", str2[] = "12";
new result[3];
new x = 0;

// данный код компилируется с ошибкой, т.к. массив "result" слишком мал, чтобы вместить строку "123"
result = x ? str1 : str2; // error 047: array sizes do not match, or destination array is too small

// однако такой код компилировался без единой ошибки или даже варнинга
result = x ? str2 : str1;


Исправлены баги, из-за которых компилятор ошибочно считал код недостижимым
когда в ветвлении if ветвь true заканчивается на return, а ветвь false пустая:

new const bool:TRUE = true;
if (TRUE) { return 1; }
else {}
return 0; // warning 225: unreachable code


когда после ветвления, обе ветви которого заканчиваются на return, следует метка, использованная ранее через goto:

new var = 0;
if (var == 0)
goto label_1;
if (var != 0)
return 0;
else
return 1;
label_1: // warning 225: unreachable code
return 2; // на самом деле этот код достижим, поскольку ранее
// был совершён переход ("goto") на метку "label_1"


Устранён недочёт, из-за которого компилятор позволял объявлять операторы с атрибутом public.
Пример:

public operator=(Tag:a) return _:a;

Очевидно, что атрибут public по идее не должен быть применим к операторам, однако раньше такой код компилировался без единого варнинга. Теперь же компилятор не позволит этого сделать:

error 056: arrays, local variables, function arguments and user-defined operators cannot be public (symbol "operator =(Tag:)")

DeimoS
14.09.2020, 06:31
Касаемо модифицированных инклудов - в той версии, которая прикреплена, не исправлена const-корректность для многих функций. Она исправлена только для инклудов версии 0.3DL. При этом, релизная версия иклудов под 0.3DL тоже устарела. Свежую версию можно получить только при загрузке архива с основной веткой - https://github.com/pawn-lang/samp-stdlib/archive/master.zip. Правда, опять же, тут включены функции для 0.3DL.

Nexius_Tailer
15.09.2020, 13:45
Касаемо модифицированных инклудов - в той версии, которая прикреплена, не исправлена const-корректность для многих функций. Она исправлена только для инклудов версии 0.3DL. При этом, релизная версия иклудов под 0.3DL тоже устарела. Свежую версию можно получить только при загрузке архива с основной веткой - https://github.com/pawn-lang/samp-stdlib/archive/master.zip. Правда, опять же, тут включены функции для 0.3DL.
Это довольно давно известно (https://github.com/pawn-lang/samp-stdlib/issues/27) и даже с того момента ничего не предпринято

DeimoS
15.09.2020, 22:59
Это довольно давно известно (https://github.com/pawn-lang/samp-stdlib/issues/27) и даже с того момента ничего не предпринято

Да, я видел твоё сообщение. Потому, собственно, сам не стал туда писать и решил просто сообщить на форуме, что ссылка ведёт на кривые файлы.

Pro_Coder
15.10.2020, 21:04
Вы не думали, почему бы не сделать двумерный массив для enum ?

https://pro-pawn.ru/showthread.php?12379-Массивы-в-ранге&p=61896&viewfull=1#post61896

Например, я хотел хранить несколько имен в p_Name[4][MAX_PLAYER_NAME + 1] , но мне выдает ошибка

enum e_pInfo {
p_ID,
p_Password[64 + 1],
p_Salt[64 + 1],
p_Name[4][MAX_PLAYER_NAME + 1]
};
new pInfo[MAX_PLAYERS][e_pInfo];



error 001: expected token: "}", but found "["
error 010: invalid function or declaration

ihNNNNNify
16.10.2020, 00:10
Вы не думали, почему бы не сделать двумерный массив для enum ?

https://pro-pawn.ru/showthread.php?12379-Массивы-в-ранге&p=61896&viewfull=1#post61896

Например, я хотел хранить несколько имен в p_Name[4][MAX_PLAYER_NAME + 1] , но мне выдает ошибка

enum e_pInfo {
p_ID,
p_Password[64 + 1],
p_Salt[64 + 1],
p_Name[4][MAX_PLAYER_NAME + 1]
};
new pInfo[MAX_PLAYERS][e_pInfo];



error 001: expected token: "}", but found "["
error 010: invalid function or declaration


Покажи строки на которые указывают ошибки

Pro_Coder
16.10.2020, 00:26
p_Name[4][MAX_PLAYER_NAME + 1]
pawn не поддерживает двумерный массив в enum

DeimoS
16.10.2020, 07:33
Вы не думали, почему бы не сделать двумерный массив для enum ?

https://pro-pawn.ru/showthread.php?12379-Массивы-в-ранге&p=61896&viewfull=1#post61896

Например, я хотел хранить несколько имен в p_Name[4][MAX_PLAYER_NAME + 1] , но мне выдает ошибка

enum e_pInfo {
p_ID,
p_Password[64 + 1],
p_Salt[64 + 1],
p_Name[4][MAX_PLAYER_NAME + 1]
};
new pInfo[MAX_PLAYERS][e_pInfo];



error 001: expected token: "}", but found "["
error 010: invalid function or declaration


А ты не думал разобраться в том, что из себя на самом деле представляет enum?

Да и зачем хранить сразу 4 ника? Если это именно разные ники и использоваться при игре будет только один - логично хранить только его в памяти сервера, а остальные оставить в БД. Если же это просто несколько разновидностей одного и того же ника, то пихать их в такой "массив" - самая неудачная идея из всех возможных, ибо сам через пару месяцев будешь с трудом вспоминать какой именно индекс такого массива к какому нику относится. Гораздо лучше под каждый ник выделить свою константу, дав ей нормальное информативное имя, и работать с ней.

Ну и если всё же очень хочется извращений, то можно сделать так:
enum e_PLAYER_NAMES
{
PLAYER_NAME_1[MAX_PLAYER_NAME],
PLAYER_NAME_2[MAX_PLAYER_NAME],
PLAYER_NAME_3[MAX_PLAYER_NAME],
PLAYER_NAME_4[MAX_PLAYER_NAME],
};

enum e_pInfo {
p_ID,
p_Password[64 + 1],
p_Salt[64 + 1],
p_Name[e_PLAYER_NAMES]
};
new pInfo[MAX_PLAYERS][e_pInfo];

Daniel_Cortez
16.10.2020, 16:06
Вы не думали, почему бы не сделать двумерный массив для enum ?
Вы даже не представляете, сколько раз этот вопрос задавали разработчикам компилятора...

Ответ на самом деле предельно простой: enum - это не аналог struct из C/C++, это просто enum с расширенным синтаксисом в сравнение с теми же C и C++.
Например, такой код:

enum pInfo
{
pPassHash[64 + 1],
pLevel
};

- это всего лишь синтаксический сахар для

enum pInfo
{
pPassHash,
pLevel = pPassHash + pInfo:(64 + 1)
};

Единственная разница лишь в том, что для первого варианта "sizeof(player_info[pPassHash])" вернёт 65, а для 2-го - 1. Насколько знаю, это единственный случай, когда sizeof возвращает "размер" для чего-то, что на самом деле не является массивом.

Pro_Coder
23.10.2020, 03:42
У меня тут вопрос возник


new test_1[MAX_PLAYERS char] = {3, ...};

Почему такой метод не работает, если {3, ...} должно заполнять все ячейки?
Или у вашего компилятора такой баг исправлен?

DeimoS
23.10.2020, 11:58
У меня тут вопрос возник


new test_1[MAX_PLAYERS char] = {3, ...};

Почему такой метод не работает, если {3, ...} должно заполнять все ячейки?
Или у вашего компилятора такой баг исправлен?

Почему же не работает?
https://i.imgur.com/UnmzbjT.png

Pro_Coder
23.10.2020, 12:34
А в чем тогда отличие от фигурных скобках ?

test_1{0}

https://ibb.co/8r2Tp6J


new test_1[MAX_PLAYERS char] = {123, ...};
new test_2[MAX_PLAYERS char];

main() {
test_2{0} = 123;

print("\n\n\n\n\n");
printf("%i", test_1{0});
printf("%i", test_2{0});
print("\n\n\n\n\n");
}

DeimoS
23.10.2020, 13:27
А, извиняюсь. Ты же с битами хочешь работать. Тупанул.

Лучше пусть тебе Daniel_Cortez ответит, чтоб я чего-нибудь лишнего не сморозил.

Daniel_Cortez
24.10.2020, 19:27
А в чем тогда отличие от фигурных скобках ?
В том, что с фигурными скобками производится доступ не к ячейкам, а к отдельным байтам массива.
Если нужно определённым значением инициализировать не ячейки, а все байты массива, то в Pawn это напрямую не сделать. Разве что можно попробовать изловчиться с чем-то вроде такого:

new test[MAX_PLAYERS char] = { 0x03030303, ... }; // 0x03030303 = (3 << 24) | (3 << 16) | (3 << 8) | 3

, либо вручную проинициализировать циклом.

Daniel_Cortez
02.01.2021, 12:37
"Неофициальный" релиз 3.10.10+ от 02.01.2021.

Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

Изменения с момента предыдущего релиза:
Добавлено 4 новых диагностики:
warning 245: enum increment "%s" has no effect on zero value (symbol "%s")
Срабатывает, когда инкремент перечисления со знаком "<<=" или "*=" не имеет эффекта над элементом перечисления, равным нулю.
Обычно это является признаком ошибки, когда пользователь забыл указать значение для самого первого элемента перечисления.

// Допустим, разные достижения игрока хранятся в виде битовых флагов.
enum ePlayerFlags (<<= 1)
{
// Пользователь забыл указать значение для pfEmailConfirmed, из-за чего элемент
// перечисления оказался равен нулю. Инкремент будет бесполезен, т.к. (0 << 1) = 0.
pfEmailConfirmed, // 0
pfTutorialCompleted, // warning 245: enum increment "<<= 1" has no effect on zero value (symbol "pfEmailConfirmed")
};

warning 246: multiplication overflow in enum element declaration (symbol "%s")
Срабатывает, когда для перечисления указан инкремент со знаком "*=" и при объявлении очередного элемента перечисления из-за умножения происходит целочисленное переполнение.

enum (*= 1024)
{
eField1 = 1,
eField2, // 1024
eField3, // 1048576
eField4, // 1073741824
eField5 // warning 246: multiplication overflow in enum item declaration (symbol "eField5")
};

warning 247: use of operator "%s" on a "bool:" value(; did you mean to use operator "%s"?)
warning 247: use of operator "%s" on "bool:" values(; did you mean to use operator "%s"?)
Предупреждает о подозрительных операциях над логическими значениями (тег "bool:"), а также в некоторых случаях предлагает использовать правильный оператор, если есть возможность его угадать.
Пример:

new bool:success = Func();
if (~success) // warning 247: use of operator "~" on a "bool:" value; did you mean to use operator "!"?

В данном примере допущена опечатка: скорее всего, автор хотел использовать на значении с тегом "bool:" логическое отрицание (знак "!") вместо битовой инверсии ("~").
Суть ошибки в том, что любые ненулевые значения интерпретируются как true, из-за чего битовая инверсия логического значения всегда даёт положительный результат.


Константа
Числовое представление
Битовая инверсия ("~")
Интерпретируется как


false
0x00000000
0xFFFFFFFF
true


true
0x00000001
0xFFFFFFFE
true


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

warning 248: possible misuse of comma operator
Срабатывает, когда пользователь объединяет два выражения в одно с помощью знака ",", однако выражение перед запятой не имеет побочного эффекта (например, просто считывает значение из переменной), что может являться признаком ошибки.

// Опечатка: пользователь явно хотел использовать другой знак вместо ","
// (скорее всего, это знак "<", т.к. он располагается на одной клавише с ",")
if (x , y) { /* ... */ } // warning 248: possible misuse of comma operator

Данная диагностика работает только внутри контрольных выражений в if и switch, а также в условиях циклов.

Исправлен баг, из-за которого компилятор не генерировал код для части выражения, если оно состоит из нескольких подвыражений, перечисляемых с помощью знака "," и последнее подвыражение имеет константный результат.

return (SendClientMessage(playerid, -1, "OK"), 1);
// Функция SendClientMessage() не вызывалась, т.к. компилятор не генерировал код
// для всего, что было перед константной частью выражения (", 1")


Убраны лишние сообщения warning 242 для ситуаций, когда для перечисления уже выдано сообщение warning 241.

enum (<<= 32) // warning 241: negative or too big shift count
{
eItem1 = 1,
eItem2, // warning 242: shift overflow in enum item declaration (symbol "eItem2")
eItem3 // warning 242: shift overflow in enum item declaration (symbol "eItem3")
// Предупреждения о переполнении при сдвиге (warning 242) по сути верны, но
// в данной ситуации они только лишний раз отвлекают пользователя, т.к.
// компилятор уже предупредил о неправильном значении сдвига (warning 241).
};

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

forward Func(const a[] = { 1, 2, 3 });
stock Func(const a[] = { 3, 4, 5 }) // error 025: function heading differs from prototype
return a[0];

Теперь компилятор выдаёт ошибку, когда #pragma warning push используется больше раз, чем #pragma warning pop (когда пользователь использует "push", но забывает восстановить прежнее состояние варнингов с помощью "pop"), и наоборот (т.е. использует "pop", забыв до этого использовать "push").

#pragma warning disable 238
#pragma warning push
main(){}
// error 001: expected token: "#pragma warning pop", but found "-end of file-"


#pragma warning pop // error 026: no matching "#pragma warning push"
main(){}

Исправлены некорректные сообщения об ошибках, выдаваемые, когда вместо массива пользователь пытался получить элемент из одиночной переменной, либо когда переменной/массива с указанным названием не существовало.

main() {
return arr[0]; // массив с именем "arr" не объявлен
}

До исправления:


test.pwn(2) : error 028: invalid subscript (not an array or too many subscripts): "var"
test.pwn(2) : warning 215: expression has no effect
test.pwn(2) : error 001: expected token: ";", but found "]"
test.pwn(2) : error 029: invalid expression, assumed zero
test.pwn(2) : fatal error 107: too many error messages on one line

Правильным здесь является только первое сообщение (о неправильном идентификаторе, из которого пытаются получить элемент массива); остальные некорректны и являются результатом того, что наткнувшись на неподходящий/необъявленный идентификатор, компилятор не пытается обработать индексную часть ("[0]" в примере выше), а вместо этого сразу ожидает окончание выражения (символ ";").
После исправления компилятор выдаёт только одно корректное сообщение и не прерывает компиляцию из-за фатальной ошибки, продолжая анализировать код дальше.
Исправлены некорректные сообщения об ошибках, выдаваемые, когда пользователь пытался объявить локальную переменную с помощью ключевого слова stock (локальные переменные можно объявлять только с помощью спецификаторов new и static).

main() {
stock x = 0;
return x;
}

До исправления:


test.pwn(2) : error 029: invalid expression, assumed zero
test.pwn(2) : error 017: undefined symbol "x"
test.pwn(2) : warning 215: expression has no effect
test.pwn(3) : error 017: undefined symbol "x"

После исправления компилятор выдаёт более понятное сообщение о неправильном объявлении:


test.pwn(2) : error 010: invalid function or declaration

, после чего не отвлекает пользователя лишними сообщениями из-за необъявленной переменной "x" (т.е. объявление обрабатывается корректно, как если бы оно было сделано с помощью ключевого слова new или static).
Исправлено ложное срабатывание fatal error 103: insufficient memory, прерывающее компиляцию в случаях, когда из-за ошибки пользователя оператор case использовался вне конструкции switch (#574 (https://github.com/pawn-lang/compiler/issues/574)).
Исправлено падение компилятора при попытке переобъявить корневую константу перечисления (#403 (https://github.com/pawn-lang/compiler/issues/403)).
Исправлено отсутствие предупреждения при попытке переобъявить корневую константу пустого перечисления (#575 (https://github.com/pawn-lang/compiler/issues/575)).
Исправлены ложные срабатывания warning 242 при использовании инкремента перечисления "<<= 0".
Исправлены ложные срабатывания warning 240 на статических (static) локальных переменных.
В тексте warning 218 ("old style prototypes used with optional semicolumns") исправлена опечатка ("semicolumns" => "semicolons").

tnc
04.01.2021, 00:44
Не хочешь настроить в своем репо Github Actions?

Daniel_Cortez
05.01.2021, 07:12
Не хочешь настроить в своем репо Github Actions?
Зачем? Он уже настроен в апстриме, да и моими релизами пользуется не так много людей, чтобы что-то автоматизировать.

Pro_Coder
06.01.2021, 17:46
Если использовать такой метод, выдаст warning 244: enum element "Test_None" not handled in switch. Это какой-то баг компилятора, или так и должно?


enum TestType {
Test_None = 0,
Test_Player,
Test_Vehicle
};

new TestType:infoTest[MAX_PLAYERS] = {Test_None, ...};

switch (infoTest[playerid])
{
//case Test_None: {}
case Test_Player: {}
case Test_Vehicle: {}
}

Daniel_Cortez
06.01.2021, 18:49
Если использовать такой метод, выдаст warning 244: enum element "Test_None" not handled in switch. Это какой-то баг компилятора, или так и должно?
Варнинг на то и нацелен, чтобы отлавливать элементы перечислений, которые забыли обработать в switch. Если предупреждение ложное, его легко устранить, добавив пустой case (или default, но тогда, если в следующий раз на самом деле что-то забудете, диагностика уже не сработает).

Pro_Coder
06.01.2021, 18:53
Варнинг на то и нацелен, чтобы отлавливать элементы перечислений, которые забыли обработать в switch. Если предупреждение ложное, его легко устранить, добавив пустой case (или default, но тогда, если в следующий раз на самом деле что-то забудете, диагностика уже не сработает).

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

Daniel_Cortez
08.01.2021, 07:47
Pro_Coder, забыл упомянуть, есть ещё такой способ:

const TestTag:TEST_NONE = TestTag:-1;
enum TestTag
{
TEST_PLAYER,
TEST_VEHICLE
};

Суть выноса TEST_NONE за пределы enum в том, что эта константа перестанет быть связанной с перечислением и диагностика warning 244 больше не будет требовать обязательного наличия кейса под неё в switch, и при этом не будет генерироваться никакого лишнего кода.

tnc
14.02.2021, 11:32
Я уже как-то писал, что было бы не плохо иметь возможность использовать прогрессивную инициализацию для 3ех и более мерных массивов. Часто встречаюсь последние время с этим из-за чего приходится инициализировать значения циклом.

@Daniel_Cortez, возможно найдешь время, чтобы добавить такую фичу? Это было максимально полезно.

Daniel_Cortez
20.02.2021, 10:36
Я уже как-то писал, что было бы не плохо иметь возможность использовать прогрессивную инициализацию для 3ех и более мерных массивов. Часто встречаюсь последние время с этим из-за чего приходится инициализировать значения циклом.

@Daniel_Cortez, возможно найдешь время, чтобы добавить такую фичу? Это было максимально полезно.
Последний раз, когда я смотрел на код инициализации массивов, для меня это было запутанное спагетти, из которого не удалось понять практически ничего. Возможно, как-нибудь потом и получится в этом разобраться, но пока что в компиляторе есть ещё куча других проблем, которые нужно устранить, равно как и функционала, который я планировал реализовать ещё с прошлого года.

tnc
20.02.2021, 14:19
Последний раз, когда я смотрел на код инициализации массивов, для меня это было запутанное спагетти, из которого не удалось понять практически ничего. Возможно, как-нибудь потом и получится в этом разобраться, но пока что в компиляторе есть ещё куча других проблем, которые нужно устранить, равно как и функционала, который я планировал реализовать ещё с прошлого года.

окей, в каких файлах находится код инициализации? Я попробую в свободное время порыть его

Daniel_Cortez
20.02.2021, 20:28
окей, в каких файлах находится код инициализации? Я попробую в свободное время порыть его
Файл "sc1.c", функция "initials()". Если будут вопросы - не стесняйся спросить в ЛС.

Daniel_Cortez
02.05.2021, 18:37
"Неофициальный" релиз 3.10.10+ от 02.05.2021.

Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/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()), модифицируемых с помощью операторов "++" и "--".

main()
{
new a[1] = { 0 };
printf("%d", a[0]); // Без "++"/"--" значение a[0] ("0") выводится правильно
printf("%d", a[0]++); // Но из-за "++" вместо "0" выводилось неправильное (мусорное) значение
}


Введены более строгие правила для заголовков функций (т.е. как для объявлений, так и для определений):
Если в заголовке присутствует спецификатор класса, то определение функции тоже должно содержать этот спецификатор.

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").

Цель новых правил - исключить труднодиагностируемые случаи, когда классовые спецификаторы не имеют эффекта или приводят к неправильной кодогенерации (см. #621 (https://github.com/pawn-lang/compiler/issues/621), #624 (https://github.com/pawn-lang/compiler/issues/624)).


Исправлен баг, из-за которого в 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 (https://github.com/pawn-lang/compiler/issues/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 (https://github.com/pawn-lang/compiler/issues/627#issuecomment-753583917)).


Исправлен баг, в редких случаях приводивший к падению компилятора (см. #398 (https://github.com/pawn-lang/compiler/issues/398#issuecomment-791512488)).
Проблема была обнаружена ещё 2 года назад, однако её решение затрудняло то, что она проявлялась крайне редко и только в сборках для Linux и OS X.

P.S.: Всем удачных майских выходных! Особенно тем, кому тоже повезло с 10-дневными "каникулами" =)

Falcon
14.05.2021, 18:40
"Неофициальный" релиз 3.10.10+ от 02.05.2021.
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip

По-моему инклуды здесь не модифицированные

Еще хотелось бы спросить на счет OnPlayerCommandText: При использовании кода

OnPlayerCommandText(playerid, "/command")
дабы вызвать этот паблик, мы получаем варнинг:

warning 239: literal array/string passed to a non-const parameter

Вопрос: Это баг ? (Потому что сам public не вызывает warning, только его использование как функции)

Если нет, то как лучше поступить:
Модифицировать инклуд (задать cmdtext[] как const), тем самым избавиться от варнинга (при этом сам паблик продолжает работать нормально) ?
Или же стоит вообще не использовать OnPlayerCommandText как вызов функции с заданными параметрами (Даже не знаю корректен ли такой код) ?

Fallen A.
16.05.2021, 02:07
По-моему инклуды здесь не модифицированные

Еще хотелось бы спросить на счет OnPlayerCommandText: При использовании кода

OnPlayerCommandText(playerid, "/command")
дабы вызвать этот паблик, мы получаем варнинг:

warning 239: literal array/string passed to a non-const parameter

Вопрос: Это баг ? (Потому что сам public не вызывает warning, только его использование как функции)

Если нет, то как лучше поступить:
Модифицировать инклуд (задать cmdtext[] как const), тем самым избавиться от варнинга (при этом сам паблик продолжает работать нормально) ?
Или же стоит вообще не использовать OnPlayerCommandText как вызов функции с заданными параметрами (Даже не знаю корректен ли такой код) ?

И то, и другое.

tnc
29.05.2021, 03:30
Хотелось бы ещё узнать насколько будет проблематично разрешить в перегрузке операторов принимать массивы? Можно ли добиться такого результата?


stock bool:operator==(oper1[], oper2[])
{
return strcmp(oper1, oper2) == 0;
}


Если это возможно с минимальными изменениями в коде, то почему бы не дать такую возможность?

Daniel_Cortez
30.05.2021, 19:00
Хотелось бы ещё узнать насколько будет проблематично разрешить в перегрузке операторов принимать массивы? Можно ли добиться такого результата?


stock bool:operator==(oper1[], oper2[])
{
return strcmp(oper1, oper2) == 0;
}


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

tnc
30.05.2021, 21:44
Очень проблематично. Если для массивов не предусмотрено даже обычных, не перегруженных операций (за единственным исключением в виде присвоения), то о каких перегрузках может идти речь?

Т.е: альтернативного сравнения не ждать? И никак его не реализовать? (кроме как через #emit и получения адрес, как это сделано в tdw_string)

Daniel_Cortez
31.05.2021, 18:48
Т.е: альтернативного сравнения не ждать? И никак его не реализовать? (кроме как через #emit и получения адрес, как это сделано в tdw_string)
Как ты представляешь себе сравнение массивов разной длины? Если со строками эта задача более-менее стандартизирована (есть функция strcmp(), которая возвращает -1, 0 или 1, причём аналогичная функция есть также в C и C++), то как быть, если один массив длиннее другого? Сравнивать первым делом длины массивов, или же содержимое (пока один из массивов не закончится)?
Под эту задачу нет общепринятого стандарта, поэтому ни в Pawn, ни в его "старших братьях" C и C++ решения "из коробки" нет и не предвидится. Да и не настолько это частая задача, чтобы требовать какого-то своего стандарта. К слову, подобного рода проблемы и с оператором возведения в степень (помню, кто-то не так давно предлагал такую идею), который в Pawn тоже вряд ли появится.

tnc
31.05.2021, 21:34
Как ты представляешь себе сравнение массивов разной длины? Если со строками эта задача более-менее стандартизирована (есть функция strcmp(), которая возвращает -1, 0 или 1, причём аналогичная функция есть также в C и C++), то как быть, если один массив длиннее другого? Сравнивать первым делом длины массивов, или же содержимое (пока один из массивов не закончится)?
Под эту задачу нет общепринятого стандарта, поэтому ни в Pawn, ни в его "старших братьях" C и C++ решения "из коробки" нет и не предвидится. Да и не настолько это частая задача, чтобы требовать какого-то своего стандарта. К слову, подобного рода проблемы и с оператором возведения в степень (помню, кто-то не так давно предлагал такую идею), который в Pawn тоже вряд ли появится.

Эмм, а разве memcmp (https://en.cppreference.com/w/cpp/string/byte/memcmp) не подойдет?

Daniel_Cortez
31.05.2021, 22:00
Эмм, а разве memcmp (https://en.cppreference.com/w/cpp/string/byte/memcmp) не подойдет?
А разве в ней есть аргумент для размера второго массива?

tnc
31.05.2021, 22:29
А разве в ней есть аргумент для размера второго массива?

Приведи пример, где это нужно, пока что не понимаю о чем ты

Daniel_Cortez
01.06.2021, 19:02
Приведи пример, где это нужно, пока что не понимаю о чем ты
О том, что у memcmp всего один аргумент count, а значит она может сравнивать массивы только при условии, что их длины одинаковы. Изначально разговор был про массивы разной длины.

$continue$
11.06.2021, 13:26
Не уверен, но похоже что ложное срабатывание диагностики. Например вот так:


#include <a_samp>

stock SomeFunction(str[] = "", const size = sizeof(str))
{
new len = strlen(str);
if (len > 0)
{
strcat(str, "write to string array", size);
}
else
{
// some other logic
}
}
main()
{
SomeFunction("");
}


Мы падаем в ветку else (т.к передана пустая строка). Там происходит какая-то логика. Но компилятор с нас просит const, хотя мы пишем в массив (если падаем в if ветку). Более "ходовой" пример с таким кодом можно глянуть в alternative dialogs (https://pastebin.com/kzHVBMXe), функция ShowPlayerAltDialog. С пустыми строками оно вызывается для закрытия диалога, как это можно сделать с ShowPlayerDialog.

Daniel_Cortez
11.06.2021, 15:54
Не уверен, но похоже что ложное срабатывание диагностики.
Warning 239 выдаётся на 17-й строке из-за того, что в SomeFunction() передаётся строковый литерал.
Если сделать так:

static const empty_str[] = "";
SomeFunction(empty_str);

то никакого варнинга не будет.

Впрочем, можно ещё сделать вот так:

SomeFunction(_);

Что по сути тоже является передачей строкового литерала (который, естественно, может оказаться модифицирован внутри функции, т.к. аргумент без const), но компилятор не предупредит об этом. Попробую сегодня сделать об этом issue в репо компилятора, а пока что делать так, как в последнем примере, не рекомендую.

UPD: Это не баг, см. пост ниже.

Daniel_Cortez
12.06.2021, 15:09
Касаемо моего вчерашнего сообщения:

Впрочем, можно ещё сделать вот так:

SomeFunction(_);

Что по сути тоже является передачей строкового литерала (который, естественно, может оказаться модифицирован внутри функции, т.к. аргумент без const), но компилятор не предупредит об этом. Попробую сегодня сделать об этом issue в репо компилятора, а пока что делать так, как в последнем примере, не рекомендую.
Немного покопался в коде компилятора и, как оказалось это не баг: в таких случаях компилятор не передаёт ссылку на строку напрямую, а сначала создаёт в куче копию строки/массива по умолчанию и уже её передаёт - эту копию можно безопасно модифицировать внутри функции.

Daniel_Cortez
13.08.2022, 15:48
"Неофициальный" релиз 3.10.10+ от 13.08.2022.

Скачать: https://www.dropbox.com/s/v5gvuwi0s2dq69t/pawnc-3.10.10x.zip?dl=1
Модифицированные инклуды SA-MP: https://github.com/pawn-lang/samp-stdlib/archive/0.3.7-R2-1-1.zip
Исходный код: https://github.com/Daniel-Cortez/pawn-3.10/tree/master-fixes

Изменения с момента предыдущего релиза:

Диагностика warning 252 ("значение переменной изменено, но не используется") теперь работает для операторов ++, --, а также для составных операторов присвоения (+=, -=, *= и пр.)

AddOne(arg) {
// переменная увеличена на единицу ПОСЛЕ передачи её значения в return,
// т.е. её новое значение после инкремента никак не используется
// (возможно, автор кода вместо "arg++" хотел написать "++arg" ?)
return arg++; // warning 252: variable has its value modified but never used: "arg"
}


Диагностика warning 240 ("присвоенное значение не используется") теперь указывает на ту строку, на которой произошло предыдущее присвоение (которое не используется), а не текущее.

var = 1; // теперь warning 240 выводится для этой строки
// ...
var = 2; // раньше предупреждение указывало на эту строку, а предыдущее
// присвоение приходилось выискивать самостоятельно


Отменено введённое ранее требование на перечисление всех спецификаторов функции в последующих объявлениях и определении.
Пример:

forward public Func();

// В определении функции нет спецификатора "public", но компилятор не станет
// считать это ошибкой, как было в предыдущем билде (05/2021).
Func(){}

Тем не менее, всё ещё нельзя присваивать спецификаторы static и public после того, как функция уже определена.

Func()
{
// ...
}

// Функция уже определена, нельзя добавить к ней спецификатор "static" или "public"
forward public Func(); // error 025: function heading differs from prototype

// В то же время "stock" можно добавить даже после определения, т.к. он не влияет
// на кодогенерацию и только подавляет предупреждение, если функция не используется
forward stock Func(); // OK


Исправлено ложное срабатывание warning 240 в редких случаях, когда внутри цикла с помощью goto совершался переход на метку, объявленную далее внутри того же цикла (пример (https://github.com/pawn-lang/compiler/issues/669#issuecomment-895317894)).

Исправлено падение компилятора, которое могло произойти из-за незавершённой конструкции do-while, в которой по ошибке забыто слово while.

main()
{
do {} // В цикле не хватает "while", но вместо того, чтобы вывести ошибку
// об отсутствии ключевого слова, компилятор просто падал.
}


Исправлено игнорирование спецификации размера возвращаемого массива в объявлениях операторов.
По правилам языка операторы не могут возвращать массивы, однако изначальный разработчик компилятора забыл добавить для этого соответствующую проверку.

// теперь "[10]" в этом объявлении считается за ошибку,
// как и должно было быть изначально
native Tag:[10]operator+(Tag:a, Tag:b) = 0;


Обеспечена сборка со статической библиотекой времени выполнения.
Это приведёт к увеличению размера файлов "pawncc.exe" и "pawnc.dll", однако теперь для работы компилятора не потребуется установка Visual C++ 2010 Runtime (нужные части библиотеки будут встроены в сам компилятор).
В стоковом компиляторе (распространяемом вместе с релизами SA-MP) не нужно ничего дополнительно устанавливать, поэтому логично чтобы и здесь не было этого требования.

tify
04.09.2022, 07:31
Я начал пользоваться оператором "__emit" и заметил отсутствие макро-инструкций "*ref.u.alt/pri".

P.S. за статическую линковку VC++2010 отдельное спасибо.