Comdiv писал(а):
Цитата:
Пожалуйста, укажите, как можно толковать переполнение, чтобы цикл FOR корректно завершался на границе диапазона.
Например, так
...
Такие трактовки могут быть чисто умозрительными и для того же FOR можно просто воплотить желаемое поведение, наподобие того, что уже воплощено Вами.
Спасибо, я вот не додумался, что неопределенность переполнения можно так истолковать. Т.е. можно сделать FOR, который не зацикливается и сказать "это стандартный FOR, только переполнение у нас специфическое". Получается, что переполнение дает некое особое значение, отличное от остальных чисел. И это особое значение больше любого числа в сравнении <=, но меньше любого в сравнении >=. Т.е. нужно расширить множество значений целых чисел, добавив туда какое-то особое значение. Хотя, например, при трансляции в JS это не столь и обременительно.
Можно также, например, принять такую трактовку "если переполнение в инкременте или декременте, который завершает тело цикла WHILE, то этот цикл завершается". Тогда тоже FOR бы не зациклился.
Но в любом случае ситуация "может при определенной трактовке выполниться правильно даже на краю диапазона" хуже чем "всегда выполняется правильно для всех значений". Лучше уж не трактовать возникшее переполнение, а просто возникновения не допускать, ведь переполнение - это какая-то аварийная особая ситуация. И, в отличии от деления на 0, тут можно легко ее избежать.
Ведь почему произошло переполнение? Потому что выполнился инкремент (ну или декремент). Но инкремент при выполнении FOR не самоцель, он нужен для получения следующего значения в последовательности чисел. А когда тело цикла выполнилось в последний раз, следующее значение не нужно, ведь цикл должен обработать только те значения, что содержатся в диапазоне. А раз не нужно значение, то не нужен и инкремент! Ведь этот инкремент может вызвать переполнение, которого лучше избежать, чем перехватывать потом изощренной трактовкой.
Почему же инкремент выполняется? Потому что он прописан в стандарте - там жестко прописан неправильный механизм перебора значений, механизм с лишним инкрементом.
Вот в чем причина, а не в трактовке неопределенности. Поэтому, чем выискивать такую трактовку, которая позволяет даже столь дефектному стандарту исполниться правильно, лучше признать сразу, что стандарт дефектный и заменить другим. Таким, который без всяких трактовок верно выполняется. И не прописывать конкретный механизм, пусть это выбирает компилятор, в зависимости от константности параметров и величины самих параметров. В теме "
Модификация Ofront. Реализуем "правильный" FOR" я рассмотрел несколько таких случаев, получается довольно эффективно даже на уровне С (еще более эффективный код получился бы с учетом команд конкретного процессора). Расплата за это - усложненный компилятор, но даже самый простой механизм реализации незацикливающего FOR лучше, чем стандарт с переполнением.