Показать сообщение отдельно
Старый 20.03.2005, 11:44   #429
Vam

AGFC
Гость
 
Сообщений: n/a

По умолчанию Re: Декомпилятор скриптов Готики

2Donate2005:
Поясни, как нужно правильно прозванивать (вызывать) функции экзешником!
Такой проверки вообще не существует, можно полагаться только на разум разработчиков скриптов и логически домыслить, что должна возвращать функция. Наиболее часто встречаемый случай: внутри блока с условием if записан return TRUE или FALSE, после окончания блока функция заканчивается без указания возвращаемого значения, следовательно, после блока if необходимо записать return со значением противоположным по смыслу значению внутри блока.

Рассмотрим очень простой пример (он попадает не в ошибку, а во внимание):
func int dia_uhrt_helloreject_condition()
{
* *if(!ENTEREDINNERCIRCLE && hero.aivar[AIV_INVINCIBLE])
* *{
* * * *return TRUE;
* *};
* *return FALSE;
};

1. Функция должна однозначно возвращать int.
2. Внутри блока if есть возвращаемое значение, после блока его нет.
3. Если условие истинно, то возвращается TRUE, значит по логике: если условие ложно, то должно возвращаться FALSE, вот его и нужно записать после блока, что и сделано красным цветом.

Возникает законный вопрос: как работает игра, проводит ли такая запись к ошибке - сразу скажу, что в большинстве случаев ошибки не возникает и все работает правильно, но в некоторых сложных случаях ошибка возможна, причем она может быть не постоянной, а плавающей в зависимости от некоторых условий.
Все дело в том, что после условия if в стек (вся внутренняя связь датника с экзешником осуществляется через стек) заносится результат выражения под if, следовательно, если условие истина в стеке будет 1 (TRUE), если ложно - 0 (FALSE). Далее, возвращаемое функцией значение есть последнее значение записанное в стеке -> данная функция могла бы выглядеть вот так
func int dia_uhrt_helloreject_condition()
{
* *if(!ENTEREDINNERCIRCLE && hero.aivar[AIV_INVINCIBLE])
};
но здесь появляется ошибка синтаксиса, после условия if обязятельно наличие блока {...}; который отсутствует. Далее, по первоначальному варианту, если идти через if в стеке будет 1,1 (первая 1 - результат if, вторая 1 - результат return TRUE), если же идем минуя if в стеке будет только 0 (результат if), записав на выходе функции return FALSE, мы поместим в стек 0 и выровняем стек при разных условиях (это, в принципе, не обязательно). Просто я хочу сказать, что дописав строку (логически понимая для чего, а не бездумно, лишь бы ошибки не было), во-первых - дополнительной ошибки мы не внесем, во-вторых - приведем в соответствие с синтаксисом и устраним замечание по функции. Компилятор не может проверять одни функции на правильность и не проверять другие, все правила для него строги и одинаковы для всех функций.
Человек же может поступить не так, записав в одном месте при декларации функции int и ничего не возвратив, а в другом void. Это мы довольно часто наблюдаем в функциях обработки диалогов: func int ххх_condition() - должна возвращать значение, а функция func void ххх_info() - должна иметь тип void и ничего не возвращать.
Ответить с цитированием