Использование переменной счетчика после цикла FOR-Loop

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Использование переменной счетчика после цикла FOR-Loop

Сообщение Rang » 03.09.2018 17:10:42

Столкнулся с проблемой при переходе с Delphi 2007 на FPC.

Есть код:
Код: Выделить всё
for i := 0 to 10 do
  Continue;
Writeln('Result: ', i);


На Delphi 2007:
Код: Выделить всё
Result: 11


На FPC:
Код: Выделить всё
Result: 10


То есть, в Delphi в конце цикла идет увеличение переменной и потом выход из него, в FPC сразу выход из цикла.
Все бы логично, и Delphi предупреждает, что переменная 'i' может быть неопределенной после цикла.

Суть в том, что есть крупный проект, в котором часто использовали такой трюк Delphi и сейчас возникла проблема с поиском и устранением этих трюков на FPC.
Код выше, при компиляции в Delphi, выдает предупреждение: W1037 Variable 'i' may be undefined after loop.
А FPC никаких предупреждений не выводит и по сути отлов таких мест становится затруднительным.

Но иногда и Delphi чудит, видоизменяем код на такой:
Код: Выделить всё
for i := 0 to 10 do
  if i < 15 then
    Continue
  else
    Break;
Writeln('Result: ', i);

... теперь и Delphi не видит в этом коде проблем. Предупреждения нет.

Есть ли возможность что-то включить в FPC, чтобы эти ошибки появились?
Rang
новенький
 
Сообщения: 12
Зарегистрирован: 15.10.2015 15:44:16

Re: Использование переменной счетчика после цикла FOR-Loop

Сообщение wavebvg » 03.09.2018 21:15:33

Хочу сильно Вас расстроить. При штатном выходе из цикла по условию (без break или exit) значение неопределенно.
Это связано с тем, что при оптимизации, компилятор может использовать вместо счетчика регистр процессора, а при выходе из цикла — просто сбросить значение (pop/push).
Компилятор не всегда догадывается, что вы от него хотели, поэтому при использовании break, как в примере, предупреждений не делает. При этом, гарантий, что скомпилированный код будет всегда корректно работать — нет.
Если проект крупный, то вычитать и исправить (ну или пометить как верное, отключив на этом участке проверку) все предупреждения компилятора — дело святое.
Последний раз редактировалось wavebvg 04.09.2018 11:40:34, всего редактировалось 1 раз.
wavebvg
постоялец
 
Сообщения: 289
Зарегистрирован: 28.02.2008 04:57:35

Re: Использование переменной счетчика после цикла FOR-Loop

Сообщение Vadim » 04.09.2018 07:51:08

Rang писал(а):Есть ли возможность что-то включить в FPC, чтобы эти ошибки появились?

Это вряд ли... Потому что это не ошибка, а стандартное поведение. Delphi (как и паскаль) изначально был рассчитан на эксплуатацию контингентом, квалификация которого ниже плинтуса. :-) И такие предупреждения - это нормальное для него поведение, потому что это обучение программированию. У FPC ориентация несколько другая, именно поэтому он таких предупреждений и не даёт.
Rang писал(а):... Delphi предупреждает, что переменная 'i' может быть неопределенной после цикла.

FPC в своём руководстве точно так же оговаривает поведение переменной цикла:
• The value of the loop variable is undefined after a loop has completed or if a loop is not executed at all. If the loop was terminated prematurely with an exception or a break statement,
the loop variable retains the value it had when the loop was exited.

но кто же читает руководства? :-D
Если вкратце Break\Exit - это гарантия того, что переменная цикла сохраняет своё значение. И менно потому, что цикл не выполнен и надо проанализировать его составляющие. Во всех остальных случаях полагаться на переменную нельзя.
Что пишут в Delphi по этому поводу я никогда не интересовался, однако поведение FPC, что Вы и показали, вполне логично. А вот Delphi как раз не очень, т.к. изменять переменную цикла после работы цикла бессмысленно.
Таким образом, Ваш проект основывается на неопределённости. И Вы ничего по этому поводу предпринимать не хотите, даже несмотря на предупреждения компилятора Delphi. ;-)
По этому поводу лучше всего поговорить с разработчиками компилятора, а не с его пользователями (а мы тут, как раз такими пользователями, за редким исключением, и являемся). Вполне возможно, что есть определённый алгоритм поведения переменной и лучше опираться на него, если Вы непременно хотите делать сюрпризы пользователям Вашей программы. ;-)
Vadim
долгожитель
 
Сообщения: 2809
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Использование переменной счетчика после цикла FOR-Loop

Сообщение zub » 04.09.2018 15:03:09

>>Если вкратце Break\Exit - это гарантия того, что переменная цикла сохраняет своё значение.
Чтобы воспользоваться этой гарантией надо приложить дополнительные усилия чтобы быть уверенным что цикл закончился по Break. Очень странная ремарка - лучше не беря ее во внимание считать переменную всегда неопределенной.

ИМХО компилятор должен ругаться на попытку использования переменной без инициализации. Цикл не является способом инициализации переменной
zub
долгожитель
 
Сообщения: 2462
Зарегистрирован: 14.11.2005 23:51:26

Re: Использование переменной счетчика после цикла FOR-Loop

Сообщение Vadim » 04.09.2018 16:28:23

zub писал(а):Чтобы воспользоваться этой гарантией надо приложить дополнительные усилия чтобы быть уверенным что цикл закончился по Break.

Поэтому и не стоит злоупотреблять костылями для попыток вытрясти переменную цикла вне цикла. Я ведь об этом и написал. ;-)
Vadim
долгожитель
 
Сообщения: 2809
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Использование переменной счетчика после цикла FOR-Loop

Сообщение sign » 05.09.2018 07:26:11

Когда мне, ну, ужасть, как надо переменную цикла за циклом, я использую while ... do.
sign
энтузиаст
 
Сообщения: 960
Зарегистрирован: 30.08.2009 09:20:53

Re: Использование переменной счетчика после цикла FOR-Loop

Сообщение Rang » 07.09.2018 11:39:17

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

Согласен с тем, что если нужна переменная после\вне цикла - то проще сделать это через while..do.
Rang
новенький
 
Сообщения: 12
Зарегистрирован: 15.10.2015 15:44:16


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 3

Рейтинг@Mail.ru