PDA

Просмотр полной версии : [Вопрос] const-корректность



Elrmrnt-Kritik
14.07.2018, 00:39
Всем привет. Подскажите пожалуйста, тот факт, что константную строку нельзя передать в качестве аргумента ShowPlayerDialog, - это баг компилятора или это некая особенность? К слову, проверял и в NotePad++, и в Visual Studio Code:


new const gText[] = "какая-то строка";
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, "Название", "Текст", "Кнопка1", gText);


// error 035: argument type mismatch (argument 7)


new const gText[] = "какая-то строка";
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, "Название", "Текст", gText, "Кнопка2");


// error 035: argument type mismatch (argument 6)


new const gText[] = "какая-то строка";
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, "Название", gText, "Кнопка1", "Кнопка2");


// error 035: argument type mismatch (argument 5)


new const gText[] = "какая-то строка";
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, gText, "Текст", "Кнопка1", "Кнопка2");


// error 035: argument type mismatch (argument 4)


Аналогичная ситуация со static const. А если использовать просто new или просто static - все хорошо.

(я на этом пытаюсь выиграть в памяти, поскольку у меня порядка 30 диалогов с одинаковыми названиями и кнопками)

Daniel_Cortez
14.07.2018, 06:50
Одно из многих проявлений того, что в SA-MP Team попросту не знают Pawn и в инклудах делают всё на тяп-ляп. И это самое "тяп-ляп" остаётся и по сей день, спустя 10 лет, ибо они, как правило, не заинтересованы в исправлении багов - если только эти баги не вызывают падение сервера или иным образом мешают получать прибыль с Hosted'а.

Как бы то ни было, суть бага в том, что заголовок функции записан неправильно: массивы в аргументах указаны без атрибута const

native ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]);

в то время как правильно должно быть так:

native ShowPlayerDialog(playerid, dialogid, style, const caption[], const info[], const button1[], const button2[]);

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

Теперь об исправлении. Официального багфикса ждать, конечно же, глупо (смиритесь и продолжайте платить за Hosted, чтобы Kalcor и дальше мог ничего не делать!), но есть несколько сторонних решений:
fixes.inc (https://github.com/Open-GTO/sa-mp-fixes)
Инклуд c костылями для обхода множества багов в SA-MP. С прошлого года пополнился исправленными заголовками функций.

samp-stdlib (https://github.com/sampctl/samp-stdlib)
Набор модифицированных инклудов SA-MP. Официально они предназначены для инструмента sampctl, однако их можно использовать как прозрачную замену стандартным инклудам (т.е. просто закинуть в папку "pawno/include" с заменой).
sampctl - довольно популярный инструмент среди зарубежных разработчиков, поэтому можно не бояться, что проект окажется заброшен и не обновится при выходе новых версий SA-MP.
Не так давно я как раз добавил туда фикс const-корректности (https://github.com/sampctl/samp-stdlib/pull/6). Также стоит заметить, что скоро должны принять ещё один патч (https://github.com/sampctl/samp-stdlib/pull/9), который делает аргументы с размерами массивов необязательными (по ссылке есть примеры).


P.S.: Переместил сообщения, вопрос явно заслуживает отдельной темы.

Elrmrnt-Kritik
14.07.2018, 16:12
Из fixes.inc один баг заинтересовал меня с той точки зрения, что при помощи него можно получить и пользу - предотвратить респавн игрока при смерти.


fix name= "OnPlayerDeath"
problem Clients get stuck when they die with an animation applied.
solution Clear their animations.


Я правильно понял, если анимация из библиотеки "PED", то игрок не будет спавниться, а останется лежать на месте?