Информация об изменениях

Сообщение Re[4]: Коды ошибок и отрицательные числа от 30.01.2022 10:20

Изменено 30.01.2022 10:38 netch80

Re[4]: Коды ошибок и отрицательные числа
Здравствуйте, T4r4sB, Вы писали:

N>>1. Там, где размер участвует в арифметике — почти всегда — естественно могут появляться отрицательные значения. Да, он это говорит.


N>>Но: проблемные последствия этого являются следствием устоявшейся кривости стандарта, который не предусматривает иного действия для беззнаковых, кроме как по модулю. Если бы s-10, где s как size() какого-то контейнера равно 4, вызывало бы исключение — проблемы бы не было (или было бы сильно меньше). Считаете невозможным такой результат? — ok, не конвертировать к знаковым, пусть выбивает. Возможно, отрабатывать? — явно конвертировать.


TB>Я пишу на Расте и проблема никуда не делась.

TB>Обычный заголовок

TB>
TB>for i in 0 .. v.len()-1
TB>

TB>Является валидным полностью рабочим кодом для знакового индекса. Но в Расте этот заголовок падает на пустом векторе.

Ну это частично проблема использования закрытого отрезка. Rust позволяет использовать хотя бы полуоткрытый справа? Тогда было бы легче:

for i in 0 ..< v.len()

Это не совсем поможет при итерации в обратном порядке (тогда лучше, наоборот, полуоткрытый слева). В идеале надо поддерживать все 4, но я согласен, что это громоздко.

Вообще тут полезно сослаться на эту
Автор: netch80
Дата: 10.05.20
дискуссию, где топикстартер тянет одеяло в противоположную сторону там и Rust вспоминали, и проблемы, как при таком итерировании и где использовать цикл с предпроверкой, а где — с постпроверкой.
Вы там участвовали, и я как раз отвечал ссылкой на комментарий на Хабре. Но я оставлю ссылку для других.

TB> В С++ я бы получил ассерт при обращении по инвалидному индексу.


Имеется в виду вариант for (unsigned i = 0; i <= v.size() — 1; ++i) ?
Ну да, проблема. Потому, что работа с беззнаковыми из-за дурной подлости стандартизаторов сделана без контроля переполнений, с усечением по модулю.
Кстати, если доступ к элементу по [], а не at(), то и ассерта бы не было — скорее всего был бы сегфолт.

TB>Внимание вопрос: а какая мне нахрен разница, что программа упала не с дурацким старомодным отсталым ассертом, а с красивой модной прогрессивной молодёжной паникой?

TB>Так что нет, индексы и размеры должны быть знаковыми и только знаковыми.

Да, это общий вывод оппонентов EM в той дискуссии.
Я скорее поддерживаю, потому что польза от корректности перехода 0 <-> -1 налицо, а коллекция больше SSIZE_MAX маловероятна (рядом писал).
в целом это всё равно проблема кривости исходных средств (всех: и стандартных манер арифметики в C, и то, что у вас там в Rust оно не хочет из-за этого создавать просто пустое множество...)
Re[4]: Коды ошибок и отрицательные числа
Здравствуйте, T4r4sB, Вы писали:

N>>1. Там, где размер участвует в арифметике — почти всегда — естественно могут появляться отрицательные значения. Да, он это говорит.


N>>Но: проблемные последствия этого являются следствием устоявшейся кривости стандарта, который не предусматривает иного действия для беззнаковых, кроме как по модулю. Если бы s-10, где s как size() какого-то контейнера равно 4, вызывало бы исключение — проблемы бы не было (или было бы сильно меньше). Считаете невозможным такой результат? — ok, не конвертировать к знаковым, пусть выбивает. Возможно, отрабатывать? — явно конвертировать.


TB>Я пишу на Расте и проблема никуда не делась.

TB>Обычный заголовок

TB>
TB>for i in 0 .. v.len()-1
TB>

TB>Является валидным полностью рабочим кодом для знакового индекса. Но в Расте этот заголовок падает на пустом векторе.

[UPDATED:] На C++ это переводится: for (unsigned i = 0; i < v.len()-1; ++i)
То есть, последний элемент не используется.
Вначале я прочёл это как закрытый интервал, поспешил.
Ну тогда это вообще некорректно, потому что подобная операция на пустом контейнере не должна рассматриваться, а обдумывание должно уйти на уровень выше (чего вообще хотели достичь).

Если же речь шла бы о полуоткрытом справа интервале по всем элементам:

for i in 0 ..< v.len() (".." и есть моё "..<" для Rust)

то и проверять его надо было бы через '<', а не '<='.

Вообще тут полезно сослаться на эту
Автор: netch80
Дата: 10.05.20
дискуссию, где топикстартер тянет одеяло в противоположную сторону там и Rust вспоминали, и проблемы, как при таком итерировании и где использовать цикл с предпроверкой, а где — с постпроверкой.
Вы там участвовали, и я как раз отвечал ссылкой на комментарий на Хабре. Но я оставлю ссылку для других.

TB> В С++ я бы получил ассерт при обращении по инвалидному индексу.


Кстати, если доступ к элементу по [], а не at(), то и ассерта бы не было — скорее всего был бы сегфолт.

TB>Внимание вопрос: а какая мне нахрен разница, что программа упала не с дурацким старомодным отсталым ассертом, а с красивой модной прогрессивной молодёжной паникой?

TB>Так что нет, индексы и размеры должны быть знаковыми и только знаковыми.

Да, это общий вывод оппонентов EM в той дискуссии.
Я скорее поддерживаю, потому что польза от корректности перехода 0 <-> -1 налицо, а коллекция больше SSIZE_MAX маловероятна (рядом писал).
в целом это всё равно проблема кривости исходных средств (всех: и стандартных манер арифметики в C, и то, что у вас там в Rust оно не хочет из-за этого создавать просто пустое множество...)