Влад Жаринов писал(а):
По ходу, "лишний" инкремент может иметь смысл, если трактовать параметр как указатель позиции. Который должен иметь также положение "после конца" (и, кстати, "до начала" тогда уж
). Так у Мейера в Эйффеле,
где-то в этой книге объяснялось (в главе о типах вроде). Что не отменяет проблем...
Совершенно верно, работать с системой, в которой есть "после конца" (например фиктивная пустая запись в конце БД - EOF) и "перед началом" обычно удобнее, потому, что снимается "особость" последнего и первого элементов - они становятся не граничными, а внутренними.
Но в данном случае не так. Здесь FOR связан с целочисленным типом, который ограничен в пределах MIN(T)..MAX(T), ограничен самим ЯП! Никакого "после конца" (навроде +бесконечность) в типе Т нет, инкремент максимального значения не определен. Можно было бы считать за "после конца" флаг переполнения (переноса), но и его в самом Обероне нету (всякие SYSTEM-трюки не в счет). И тем не менее, после обработки самого последнего элемента делается лишний инкремент.
Еще 1 довод почему лишний инкремент не должен толковаться как указатель позиции "после конца". Такое положение может возникнуть лишь после самой последней итерации (из-за лишнего инкремента). Но после этой итерации цикл закончится вообще! А если закончился, так и значением указателя интересоваться дурной тон. Он не может быть ""после конца", потому что он вообще не может быть никакой! "Значение параметра цикла FOR после окончания цикла не определено", составлять свою программу рассчитывая на что-то иное - опасно и неграмотно. Также нельзя и досрочно завершать FOR, а потом по значению счетчика узнавать на каком шаге мы выпрыгнули. И изменять значения переменной цикла внутри - тоже моветон.
Цикл FOR должен выполниться для всех значений от А до В ни одного не пропуская и не повторяя дважды - вот его постусловие. Надо составлять свою программу, чтоб это постусловие было всегда. Если мы стоим после цикла, значит цикл выполнился для всех значений, поэтому нам не надо знать указатель позиции. "После конца" говорит не значение указателя, а сам факт завершения цикла!
А завершение должно быть всегда, цикл FOR, в отличие от прочих, никогда не зацикливается (не должен, если грамотно спроектирован). Цикл с шагом 1 всегда выполняется B-A+1 раз (или 0 раз, при A>B).
Да, конечно, объясняя семантику FOR через фрагмент Оберон-кода, мы можем отследить:
- чему равен параметр "после конца",
- что будет, если изменить это значение внутри цикла,
- что будет, если цикл досрочно прервать и т.д.
И вот тут и возникла проблема с инкрементом МАХ(Т)!
Такой способ задания семантики провоцирует на трюкачества, на использование FOR не по назначению.
Я бы вообще в компиляторах после окончания FOR присваивал параметру случайное число.
Уж не определено, так не определено... Отучило бы хоть от некоторых трюков.
Zorko, может сделаем?