PDA

Просмотр полной версии : [Вопрос] Так задумано или это баг



Blood
08.08.2016, 16:24
По-пробую объяснит


new hd = 1;
switch(hd)
{
case 0:
{
goto test_1;
test_1:
{
print("Сработал case 0");
}
}
case 1:
{
goto test_1;
test_1:
{
print("Сработал case 1");
}
}
case 2:
{
goto test_1;
test_1:
{
print("Сработал case 2");
}
}
}
В этом коде срабатывает case 1 , но в консоль вводится "Сработал case 2" , а не должно ли быть "Сработал case 1" ??

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

VVWVV
08.08.2016, 16:45
Это не баг, а просто последовательность генерации кода (смотрел ассемблер).
UPD: Все же это баг.

Daniel_Cortez
08.08.2016, 19:22
Похоже на баг. Суть в том, что компилятор почему-то разрешает объявлять метки с одинаковыми именами (хотя в тех же C и C++ такое запрещено), но учитывает только метку, объявленную самой последней.
Ещё интересно то, что метки видны не только внутри одного блока, но и в пределах всей функции, т.е. если объявить метку внутри блока if/switch/for/while/do/{}, она будет доступна и за пределами этого блока.
Следовательно, баг не специфичен конкретно для switch и пример из 1-го поста можно значительно упростить:


#include <a_samp>

main()
{
goto test_label;
test_label:
print("test_label 1");
return;
test_label:
print("test_label 2");
}

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

P.S.: Баг всё ещё присутствует в последней версии Pawn (4.0), поэтому я оставил багрепорт в репозитории Pawn на GitHub (https://github.com/compuphase/pawn/issues/21).

Unreal
08.08.2016, 19:49
Похоже на баг. Суть в том, что компилятор почему-то разрешает объявлять метки с одинаковыми именами (хотя в тех же C и C++ такое запрещено), но учитывает только метку, объявленную самой последней.
Ещё интересно то, что метки видны не только внутри одного блока, но и в пределах всей функции, т.е. если объявить метку внутри блока if/switch/for/while/do/{}, она будет доступна и за пределами этого блока.
Следовательно, баг не специфичен конкретно для switch и пример из 1-го поста можно значительно упростить:


#include <a_samp>

main()
{
goto test_label;
test_label:
print("test_label 1");
return;
test_label:
print("test_label 2");
}

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

P.S.: Баг всё ещё присутствует в последней версии Pawn (4.0), поэтому я оставил багрепорт в репозитории Pawn на GitHub (https://github.com/compuphase/pawn/issues/21).

сколько еще багрепортов собралось там? и будут ли они вообще обновлять Pawn?

Daniel_Cortez
08.08.2016, 20:15
сколько еще багрепортов собралось там? и будут ли они вообще обновлять Pawn?
Пока что все баги, которые я сообщал, фиксились.
По поводу следующей версии не могу знать, это вопрос к Thiadmer Riemersma. В принципе последняя версия из git-репозитория уже готова к использованию - ИМХО, даже больше, чем последняя стабильная версия (4.0), в той ещё много багов осталось.
Впрочем, вас это всё вряд ли должно интересовать по очень простой причине: в SA-MP никто обновлять Pawn не будет из-за держателей крупных серверов и обратной совместимости, чёрт бы её побрал. Давно пора признать: SA-MP открыт только для элиты, в самом грязном смысле этого слова. Лучшее, что здесь можно сделать - оставить тот же багрепорт или ссылку в репозитории (https://github.com/Zeex/pawn) с доработанным компилятором для Pawn 3.2 от Zeex.