OberonCore
https://forum.oberoncore.ru/

Почему зависает BlackBox? (переполнение в FOR)
https://forum.oberoncore.ru/viewtopic.php?f=29&t=448
Страница 1 из 1

Автор:  Alexander Shiryaev [ Пятница, 04 Май, 2007 12:09 ]
Заголовок сообщения:  Почему зависает BlackBox? (переполнение в FOR)

Модератор: заголовок темы поправлен, чтобы присутствовало слово "переполнение"
Почему зависает BlackBox? Вот от такой программы:

Код:
PROCEDURE Test*;
   VAR b: BYTE;
BEGIN
   ASSERT(MIN(BYTE) = -128);
   ASSERT(MAX(BYTE) = 127);
   FOR b := MIN(BYTE) TO MAX(BYTE) DO
   END
END Test;

Автор:  Trurl [ Пятница, 04 Май, 2007 13:10 ]
Заголовок сообщения: 

По определению ;)
Код:
b := MIN(BYTE);
WHILE b <= MAX(BYTE) DO INC(b, 1) END;
ASSERT(b > MAX(BYTE))

Автор:  Alexander Shiryaev [ Пятница, 04 Май, 2007 14:09 ]
Заголовок сообщения: 

понятно

Автор:  GameHunter [ Среда, 23 Май, 2007 11:50 ]
Заголовок сообщения: 

А разве по правилам ББ не должна здесь быть проверка на выход за границы диапазона?

Автор:  Евгений Темиргалеев [ Четверг, 24 Май, 2007 09:21 ]
Заголовок сообщения: 

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

Автор:  QWERTYProgrammer [ Среда, 28 Октябрь, 2009 00:28 ]
Заголовок сообщения:  Переполнение целых и цикл FOR

Модератор: прикреплено к уже существующей теме.
Сначала показалось не может быть:
Код:
PROCEDURE Do*;
   VAR j, N: INTEGER;
BEGIN
   N := ORD({0..30});
   FOR j := 1 TO N DO
      ASSERT(j > 0, 20);
   END;
END Do;

Если переписать через WHILE, конечно, все становится понятно.

Автор:  Info21 [ Среда, 28 Октябрь, 2009 03:22 ]
Заголовок сообщения:  Re: Переполнение целых и цикл FOR

почему было не взять N=MAX(INTEGER)?

Автор:  igor [ Среда, 28 Октябрь, 2009 10:26 ]
Заголовок сообщения:  Re: Переполнение целых и цикл FOR

Опция компилятора allchecks по умолчанию отключена.

Автор:  Info21 [ Среда, 28 Октябрь, 2009 10:56 ]
Заголовок сообщения:  Re: Переполнение целых и цикл FOR

igor писал(а):
Опция компилятора allchecks по умолчанию отключена.
А жаль.

Автор:  QWERTYProgrammer [ Среда, 28 Октябрь, 2009 23:16 ]
Заголовок сообщения:  Re: Переполнение целых и цикл FOR

Действительно, те же грабли :P
Info21 писал(а):
почему было не взять N=MAX(INTEGER)?

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

Автор:  bohdant [ Четверг, 29 Октябрь, 2009 11:08 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

В ГБ то же что и в ЧЯ. Думаю, что код одинаков.
Дело в том, что в отличии, например, от Делфи (в Си FOR другой и там глядеть нету смысла)
Цикл ГБ/ЧЯ устроен так:
сравнивается текущее значение переменной цикла и с указанным значением в TO и если значение больше (JNLE) выходим из цикла (т.е. в сучае MAX(INTEGER) и т.п. будем ходить по круга, т.к. значение никогда не будет больше максимального!!!)

Цикл в делфи устроен так:
сравнивается текущее значение переменной цикла и с инкриментированным на единицу указанным значением в TO и если не равны, продолжаем выполнение цикла

Цикл в FreePascal устроен так(мне больше всего понравилось реализация):
сравнивается текущее значение переменной цикла и с указанным значением в TO и если значение меньше (JL) , продолжаем выполнение цикла

Как по мне правильно сделано в FPC, подводных камней не вижу.

Автор:  Илья Ермаков [ Четверг, 29 Октябрь, 2009 11:39 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Так в FPC как раз и получился нормальный WHILE i < max DO :)

Автор:  bohdant [ Четверг, 29 Октябрь, 2009 11:43 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Илья Ермаков писал(а):
Так в FPC как раз и получился нормальный WHILE i < max DO :)

Наверное и в обероне нужно так сделать :wink:

там еще до цикла проверочка на диапазон стоит, т.к. в цикле проверка WHILE i < max стоит в конце

Автор:  Илья Ермаков [ Четверг, 29 Октябрь, 2009 11:46 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Я вот просто забил, наконец, на FOR. :)

Автор:  bohdant [ Четверг, 29 Октябрь, 2009 11:48 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Но сколько людей еще должны нарватся на эту фичу компиллера? :lol:
я уже не нарвусь :)

Автор:  QWERTYProgrammer [ Пятница, 30 Октябрь, 2009 02:36 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Илья Ермаков писал(а):
Так в FPC как раз и получился нормальный WHILE i < max DO :)

Не понятно, такой WHILE ведь эквивалентен FOR i=.., MAX(INTEGER)-1 и проблемы не представляет?
Или предлагается изменить смысл FOR? Но тогда кто мешает написать FOR i=.., MAX(INTEGER)+1?

Интересно, что проблемы действительно нет в gpcp: там выскакивает exception. Если в ББ включить allchecks видимо будет то же самое?

Автор:  bohdant [ Пятница, 30 Октябрь, 2009 09:57 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Chris Burrows все объяснил, причем ткнул носом в доку :oops:
Оператор

FOR v := beg TO end BY step DO statements END

эквивалентен

temp := end; v := beg;
IF step > 0 THEN
WHILE v <= temp DO statements; v := v + step END
ELSE
WHILE v >= temp DO statements; v := v + step END
END

т.е. зависон докуменирован.
igor писал(а):
Опция компилятора allchecks по умолчанию отключена.

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

Автор:  bohdant [ Пятница, 30 Октябрь, 2009 10:00 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

QWERTYProgrammer писал(а):
Или предлагается изменить смысл FOR?

нет, там все правильно работает
Код:
CMP [startval],stopval
JG exit            ;JNG
DEC [startval]

loop:
INC [startval]
...
...
...
CMP [startval],stopval
JL loop            ;JNL
exit:

Автор:  QWERTYProgrammer [ Среда, 04 Ноябрь, 2009 00:40 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

Кстати, если компилировать с allchecks, то при умножении MAX(INTEGER) на 2 почему-то ББ ошибки переполнения не выдает. При умножении на 3 или при сложении с 1 ошибка, как и должно, быть возникает :evil:
Код:
PROCEDURE Do*;
   VAR i, N: INTEGER;
BEGIN
   N := MAX(INTEGER);
   Log.Int(N); Log.Tab; Log.Set(BITS(N)); Log.Ln;
   i := N * 2;
   Log.Int(i); Log.Tab; Log.Set(BITS(i)); Log.Ln;
   i := N * 3;
   Log.Int(i); Log.Tab; Log.Set(BITS(i)); Log.Ln;
   i := N + 1;
   Log.Int(i); Log.Tab; Log.Set(BITS(i)); Log.Ln;
END Do;

Автор:  QWERTYProgrammer [ Среда, 04 Ноябрь, 2009 00:44 ]
Заголовок сообщения:  Re: Почему зависает BlackBox? (переполнение в FOR)

ASH(N,...) тоже проходит без ошибки.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/