Re: Коды ошибок и отрицательные числа
От: 5.März  
Дата: 30.01.22 06:47
Оценка: 57 (7) +2
Здравствуйте, cppguard, Вы писали:

C>А ведь как было бы приятно жить в мире доминирования неотрицательных чисел? Ошибки тогда просто уходили бы в INT_MAX, а используемый диапазон сокращался бы не вполовину, а всего на несколько элементов. Реально целые отрицательные используются для отрицательных смещений, разности двух величин и ... всё


Выбор int как типа по умолчанию не было ошибкой, все что семантически представляет собой целое число (неважно, может быть отрицательным или нет) должно быть по умолчанию знаковым типом. Реальная разница signed и unsigned не в отрицательности, их просто назвали неудачными именами. Из-за неудачного названия программисты теперь суют unsigned во все, что не может быть отрицательным.

Signed и unsigned следуют разной арифметике: signed представляет обычные числа которые следуют обычной арифметике в которой x-1 < x всегда true (именно из-за этого signed underflow/overflow навсегда объявлено UB), unsigned представляет машинные слова которые следуют modulo-2^N арифметике, где x-1 может быть как меньше так и больше x (well-defined)

В 99.99% случаев когда ты размышляешь об операциях с числами, ты и читатели твоего кода подразумевают обычную, а не модульную арифметику, так что и тип нужно использовать предназначенный для чисел, а не для машинных слов.

Поэтому C++ Core Guidelines, Google Style Guide и многие другие не рекомендуют использовать unsigned типы для чисел (только для флагов и битовых операций); Страуструп признал "беззнаковость" size_t исторической ошибкой; в новые стандарты введен ssize() возвращающий размеры в правильном типе.

C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-nonnegative

Google Style Guide: https://google.github.io/styleguide/cppguide.html#Integer_Types

B.Stroustrup “Subscripts and sizes should be signed”: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf

Длинное видео из 2013г где комитет C++ несколько раз признает ошибочность использования unsigned: https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything (12:10, 42:40, 1:02:50)
Re[11]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 20:00
Оценка: 26 (1) +3
Здравствуйте, netch80, Вы писали:

N>В любом случае, повторюсь, я поддерживаю, что в общем и целом со знаковыми удобнее хотя бы тем, что не надо следить за возможными проблемами перехода 0 -> 0-1. Вопрос был в конкретном примере.


Тема умения грамотно работать возле левого края интервалов вида [a, b) в условиях, когда выход за левый край интервала приводит к неожиданному, нежелательному или неопределенному поведению (ваши "проблемы перехода 0 -> 0-1"), является фундаментальным нативным свойством языков С и С++, да и вообще программирования в целом. Она распространяется не только на беззнаковые типы, но и на указательную арифметику, на итераторы, на потоки и на массу других концепций боле высокого уровня.

Поэтому попытки устранить эту "проблему" в области индексирования массивов — это локальное решение, которое ничего не поменяет в общем. Следить за "возможными проблемами перехода 0 -> 0-1" в более обобщенно понимании вам все равно придется ничуть не меньше чем ранее. Ценность "неудобной" беззнаковой арифметики в индексации заключается в том числе в том, что она с ранних пелёнок оповещает подрастающее поколение о существовании этой темы, с которой им в дальнейшем придется сталкиваться постоянно (независимо от того, какие типы они будут фактически использовать для индексации). Переход на знаковые типы лишь замедлит процесс формирования ценных идиом.
Best regards,
Андрей Тарасевич
Коды ошибок и отрицательные числа
От: cppguard  
Дата: 30.01.22 04:00
Оценка: 3 (1) -2
Никак не могу сопоставить в голове кое-что про коды ошибок. Со времён юникса тянется наследие в виде отрицательных значений при возврате кода ошибки целочисленным числом. Очевидно, что писать повсюду "err != -1" не очень-то приятно. Поэтому возникла мысль, что результат сохраняли в unsigned и вместо этого писали "err < INT_MAX", что читается легче и понятнее. НО! С тех же самых бородатых времён тянется наследие в виде уникальных платформ, про которые никто не слышал, правда, где underflow или overflow для int НЕ выполняется циклически, и таким образом приведение int к unsingned для отрицательных чисел считается UB (слышал, что хотят отменить).

А ведь как было бы приятно жить в мире доминирования неотрицательных чисел? Ошибки тогда просто уходили бы в INT_MAX, а используемый диапазон сокращался бы не вполовину, а всего на несколько элементов. Реально целые отрицательные используются для отрицательных смещений, разности двух величин и ... всё
Re[7]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 10:40
Оценка: +2 :)
Здравствуйте, Marty, Вы писали:

M>

M> v[i-1]...
M>[/ccode]
Костыль, уродливый костыль
Re[2]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.01.22 11:21
Оценка: +3
Здравствуйте, reversecode, Вы писали:

R>компиляторы часто оптимизируют

R>if (r == -1)
R>преобразовывая в
R>if (r < 0)

Приведите пример, пожалуйста, на каком-нибудь godbolt.
Конверсия между, например, x>0 и x!=0 (для unsigned), x<10 и x<=9 — да, такое сплошь и рядом.
А ваше — очень сомнительно.
The God is real, unless declared integer.
Re[13]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.02.22 10:15
Оценка: 1 (1) +1
Здравствуйте, B0FEE664, Вы писали:

АТ>>>>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>>>>И каков же в нашем мире результат вычитания 8 из 5?
BFE>>>В реальном мире = 0. С оговоркой, что 0 — это пусто.
N>>Точно не ноль. Скорее — исключение по невозможности совершить операцию.
BFE> Исключение в реальном мире? Это как?
BFE> Допустим вы полезли в холодильник с целью достать оттуда 8 куриных яиц, а там только 5. И тут случилось "исключение по невозможности совершить операцию". Что это может быть?

Обнаружили, что есть только 5 яиц. Задача не может быть выполнена. Действие достать яйца отменяется, происходит переход к более общей задаче и пересчёт ситуации. Может, надо изменить рецепт и ограничиться 5 яйцами. Может, надо сходить к соседям или в магазин. Много вариантов.
И, заметьте, обработка на более высоком уровне это один к одному, как если бы в коде стоял try-catch с ловлей ситуации "не хватило" в вызывающей функции.

Всё просто и банально, надо только рассмотреть реальность.

Вот если бы стояла задача "взять сколько есть яиц, но максимум 8" (причём с уточнением, что неважно, сколько реально взято! а то у вас и 5-8==0, и 3-8==0, и 0-8==0), то ваш вариант был бы адекватным задаче.

BFE>>>В мире идей = -3.

BFE>>>Выберите свой мир.
N>>Ваша вселенная удивительна, но людям там слегка не место.
BFE>В современном мире реалисты встречаются редко: одни в бога верят, другие — в отрицательные числа...

Могу только порадоваться уровню вашей самокритики. Но адекватности ей это не даёт.
The God is real, unless declared integer.
Отредактировано 02.02.2022 11:00 netch80 . Предыдущая версия .
Re[6]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 10:32
Оценка: +2
Здравствуйте, T4r4sB, Вы писали:

M>>Поэтому надо просто писать

M>>
M>>for(auto i=0u; i!=v.size(); ++i)
M>>

TB>Это другой код. Для тех, кто не знает синтаксис Раста — интервалы вида a..b там полуоткрытые.

Я, получается, не знаю. То есть в вашем исходном примере for i in 0..v.len()-1 был перебор элементов не включая последний?

Ну тогда, извините, вы скорее всего ССЗБ, что не сделали проверку на непустоту массива, потому что такая операция на пустом массиве со всех точек зрения невозможна, и вместо неё должно выполняться что-то иное.
The God is real, unless declared integer.
Re[11]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 11:03
Оценка: +2
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, T4r4sB, Вы писали:


TB>>Не лучше


TB>>Вот так правильно:

TB>>
TB>>for (auto i = v.ssize()-1; i>=0; --i) 
TB>>


M>Не вижу никаких преимуществ


Чётко и ясно прописано начальное значение, условие выхода
Re[2]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 08:42
Оценка: 1 (1)
Здравствуйте, 5.März, Вы писали:

5M>Выбор int как типа по умолчанию не было ошибкой, все что семантически представляет собой целое число (неважно, может быть отрицательным или нет) должно быть по умолчанию знаковым типом. Реальная разница signed и unsigned не в отрицательности, их просто назвали неудачными именами. Из-за неудачного названия программисты теперь суют unsigned во все, что не может быть отрицательным.


5M>Signed и unsigned следуют разной арифметике: signed представляет обычные числа которые следуют обычной арифметике в которой x-1 < x всегда true (именно из-за этого signed underflow/overflow навсегда объявлено UB), unsigned представляет машинные слова которые следуют modulo-2^N арифметике, где x-1 может быть как меньше так и больше x (well-defined)


Нет, это вы приводите как раз позднюю _ре_интерпретацию подхода, которая возникла по сути из-за хакерского переиспользования недостаточно строгих правил предшествующих стандартов.

Первые компиляторы C выполняли операции строго 1:1 и ничего почти не оптимизировали. Всякие сокращения вычисления констант, конечно, уже были, но современного уровня серьёзных переделок не было. Операции выполнялись так, как сейчас получается в GCC/Clang с -fwrapv: переполнение игнорировалось. Но: из-за одновременного наличия машин как минимум с дополнительным кодом (>99%) и обратным (отдельные модели), стандарт не смог записать это (скорее, к сожалению) для знаковых операций. Причём, такого жёсткого разделения между undefined, unspecified и implementation-defined behavior, как сейчас, тогда не было: термины вводились, но достаточно наобум. И высокой опасности эффектов от UdB не было, операциями с ними пользовались напропалую.

А уже в 1990-х, когда начали вводить высокий уровень оптимизаций, фактически как злые хакеры, "переиспользовали" лазейку в стандарте с UdB для signed для оптимизаций. Но это было на ~20 лет позже.

Всё описанное известно по документам и воспоминаниям. Ссылок в явном виде я не собирал, но если попадутся и вспомню — закину сюда. Если горит, можно, например, попросить khim@habr (с ходу нашлось такое очень близкое, но он ещё высказывался), или John Regehr, у него в блоге есть современные последствия, но и предпосылки наверняка исследовал.

Для современного состояния, конечно, ваши слова актуальны. К сожалению. Я бы таки предпочёл, чтобы вначале зафиксировались на усечении для всех случаев: это бы ускорило введение нормальных средств, в которых реакция на нарушение области значения (обычно называемое переполнением) задаётся конкретным символом операции или контекстом (лучше всего в среднем). Это бы ускорило тут прогресс лет на 20-25.

Для сравнения: в Ada разделены диапазонные целочисленные типы (вместе с базовыми стандартными знаковыми и беззнаковыми) и модульные. У диапазонных по умолчанию проверяется результат при присвоении (и при многих арифметических операциях), генерируется исключение при выходе за диапазон; это заметно дороже, но надёжно. Для модульного типа (в стиле type byte = modulo 2**8) все операции по модулю, и там по типу видно, что будет усечение. Для идеального языка я ожидаю что-то среднее: по умолчанию проверка с исключениями, но при явном указании программистом — правила упрощаются вплоть до того, как сейчас в C со знаковыми — считается, что программист всё предусмотрел и переполнения (и прочих нарушений) не будет.

5M>В 99.99% случаев когда ты размышляешь об операциях с числами, ты и читатели твоего кода подразумевают обычную, а не модульную арифметику, так что и тип нужно использовать предназначенный для чисел, а не для машинных слов.


5M>Поэтому C++ Core Guidelines, Google Style Guide и многие другие не рекомендуют использовать unsigned типы для чисел (только для флагов и битовых операций);


Они именно так мотивируют? можно цитату? (с ходу не нашёл)
А то я бы предположил скорее сложность задания реакции на переход 0 -> -1 (как в примерах из этого
Автор: netch80
Дата: 10.05.20
обсуждения). Тем более что вот прямая цитата:

ES.102: Use signed types for arithmetic
Reason

Because most arithmetic is assumed to be signed; x — y yields a negative number when y > x except in the rare cases where you really want modulo arithmetic.


По-моему, вам пора прекратить мучить сову.

5M> Страуструп признал "беззнаковость" size_t исторической ошибкой; в новые стандарты введен ssize() возвращающий размеры в правильном типе.


"Исторической ошибкой" size() является, конечно, в некоторой степени, но это факт не unsigned самого по себе — потому что размер не может быть отрицательным, а, значит, домен правильный. Страуструп как раз объясняет причины, а вы как-то очень странно читаете:

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

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

2. Нужно явно конвертировать к знаковым для таких операций, из-за п.1. Но сейчас в C и C++ по правилам, если разная знаковость у операндов, они оба приводятся к беззнаковому.

Жёсткий надёжный язык тут бы скорее отказался компилировать — приведите к одной знаковости или ступайте себе лесом. Чуть более расслабленный пересчитал бы множество значений результата и проинтерпретировал по нему — и это тоже имеет смысл. Но автоконверсия C/C++ это таки точно наследие "бородатых годов".

3. (Страуструп не писал вроде, но я добавлю: ) Из-за (естественной) знаковости ptrdiff_t никакой контейнер байтов не может занимать более половины памяти (а с учётом кодирования в дополнительном коде — и ровно половина тоже недопустима).
Поэтому или разделять разные случаи (для байтовых одни правила, для прочих другие), или можно постановить, что size() любого контейнера не может превышать SSIZE_MAX.
Может, где-то есть платформа, где это даст неожиданные проблемы (например, 16-битный мир с одним массивом в адресах от 0x1000 до 0xEFFF), но их возможные проблемы проигнорировали, тем более что там и так непонятно, что делать — ptrdiff_t должен для корректной работы быть минимум 17-битным... на такой платформе и про STL сложно говорить всерьёз.

5M>C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-nonnegative

5M>Google Style Guide: https://google.github.io/styleguide/cppguide.html#Integer_Types
5M>B.Stroustrup “Subscripts and sizes should be signed”: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf
5M>Длинное видео из 2013г где комитет C++ несколько раз признает ошибочность использования unsigned: https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything (12:10, 42:40, 1:02:50)

Последняя ссылка битая, видео, наверно, удалено.
По поводу остальных ссылок, удивительно, как вы при наличии прямых указаний авторов умудряетесь переинтерпретировать вплоть до полной противоположности.
The God is real, unless declared integer.
Отредактировано 30.01.2022 8:53 netch80 . Предыдущая версия . Еще …
Отредактировано 30.01.2022 8:53 netch80 . Предыдущая версия .
Re[4]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 01.02.22 02:12
Оценка: 1 (1)
Здравствуйте, 5.März, Вы писали:

5M>Для меня классикой уже стало наблюдать, как русские программисты выходят из тайги, отрицают все источники и авторитеты, и делают по-своему просто чтобы почувствовать себя чуть умнее, чем на самом деле. Откуда у нас столько одаренных людей берется, которые лучше знают что нужно дизайну языка, чем дизайнеры языка, ума не приложу


Страуструп создатель, а не дизайнер, дизайнер это коммитет. Точно так же, как Java сейчас разрабатывает Оракл, а не Гослинг. Авторитеты в инженерном деле это идолопоклонничество. А людям из тайги своё мнение не положено, да?

5M>Он не учит вас жизни, а приводит аргументы, что знаковые были бы для языка лучше. Есть контраргументы — высказывайте... Или в универе больше не учат, что обсуждение личности человека не является опровержением его аргументов? Почему я в англоязычных дискуссиях подобного невежества не наблюдаю?


Потому что все нетоксичные, предельно вежливые и прочее, так заведено. Я видел обсуждения внутренних групп FAANG касательно всяких священных войн, и С++ в то числе, так там яд разве что через монитор не брызгал, но внешне, особенно для ex-USSR населения, всё выглядело чинно-благородно. А самое непрятное в таких обсуждениях то, что очень быстро от фактов и логических умозаключений переходят к "the results of most computations are signed" (слова Страуструпа), то есть полностью субъективному мнению, а мнение это имеет очень большой вес. Вот и приходят в выводу "почему-бы не прислушаться к словам мэтра, он же велик". А код при этом сопровождают простые инженеры.

5M>В дотнете и тысяче других более-менее новых языков тоже все размеры и индексы знаковые, угадайте почему, вы бы лучше учились чем умничать.


Я где-то писал, что индексы должны быть беззнаковые?
Re: Коды ошибок и отрицательные числа
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 30.01.22 06:20
Оценка: +1
Здравствуйте, cppguard, Вы писали:

C>А ведь как было бы приятно жить в мире доминирования неотрицательных чисел? Ошибки тогда просто уходили бы в INT_MAX, а используемый диапазон сокращался бы не вполовину, а всего на несколько элементов. Реально целые отрицательные используются для отрицательных смещений, разности двух величин и ... всё


Отрицательные пиксельные координаты — повсюду.
Re: Коды ошибок и отрицательные числа
От: kov_serg Россия  
Дата: 30.01.22 08:42
Оценка: +1
Здравствуйте, cppguard, Вы писали:

C>Никак не могу сопоставить в голове кое-что про коды ошибок. Со времён юникса тянется наследие в виде отрицательных значений при возврате кода ошибки целочисленным числом. Очевидно, что писать повсюду "err != -1" не очень-то приятно. Поэтому возникла мысль, что результат сохраняли в unsigned и вместо этого писали "err < INT_MAX", что читается легче и понятнее. НО! С тех же самых бородатых времён тянется наследие в виде уникальных платформ, про которые никто не слышал, правда, где underflow или overflow для int НЕ выполняется циклически, и таким образом приведение int к unsingned для отрицательных чисел считается UB (слышал, что хотят отменить).


C>А ведь как было бы приятно жить в мире доминирования неотрицательных чисел? Ошибки тогда просто уходили бы в INT_MAX, а используемый диапазон сокращался бы не вполовину, а всего на несколько элементов. Реально целые отрицательные используются для отрицательных смещений, разности двух величин и ... всё


Всё очень просто 0-нет ошибки, не 0 — есть ошибка и всё.
Re: Коды ошибок и отрицательные числа
От: AeroSun  
Дата: 30.01.22 09:41
Оценка: -1
Подведу итог:
1) в стартовом посте написан сумбур
2) никто ничего не сохранял в unsigned
3) всегда сравнение было с нулём, причем 0 — это всё ок, -1 — это невалидное значение, 1+ — это коды ошибок
4) уже давно вместо этого используют typed enum — чего и вам советую
Re[2]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 30.01.22 09:53
Оценка: +1
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Во-первых, поведение целочисленных типов при приведении от signed к unsigned четко определено стандартом языка. Никаких неожиданностей здесь нет и никакого "наследия уникальных платформ" нет тоже. Если вам нравится сохранять результат в `unsigned` и проверять на `err < INT_MAX` — флаг вам в руки. Возможно тут есть какие-то подводные камни, но в общем и целом это будет гарантированно работать. Почему вы считаете, что это "лучше" проверки на отрицательность, я в упор не вижу, но если вам так больше нравится — вперед.


Потому что такой код проще формально доказывать. А конструкция "err ! =-1" подразумевает, что err может быть -2, например, хотя описание функции чётко говорит "положительное или -1". Это один момент. Второй момент — когда читаешь такой код, то сразу начинаешь думать "так, у нас может быть -1, а -2 может быть? А что это вообще за функция? Это POSIX? Возвращает какой-то handle типа файла или сокета или PID или что-то другое?". Кода возврата программ, кстати, почему-то неотрицательные.

АТ>Во-вторых, возвращаясь к вопросу знакового переполнения ("для int"), о каких "уникальных платформах" вы ведете речь? Вы о чем вообще? Постарайтесь понять простую вещь: основным источником неопределенного поведения в С и С++ является не аппаратная платформа, а компилятор. Компилятор, компилятор и только компилятор. То есть те предположения о "невозможности" неопределенного поведения, которые он широко, охотно и активно использует в процессе оптимизации кода. Неопределенное поведение в С и С++ существует именно для этого: чтобы помочь компилятору в оптимизации кода. На всех С и С++ платформах, без единого исключения, знаковые типы НЕ заворачиваются при переполнении. Никакой "уникальности" или "бородатости" в этом нет. Что за чушь? Ни на одной современной С или С++ платформе `int` НЕ заворачивается. С/С++ платформ с заворачивающимся `int` не существует и не существовало нигде и никогда, кроме, возможно, вашего воображения. Ни "уникальных", ни "повсеместных", ни "бородатых", ни "бритых" — никаких.


АТ>В-третьих, почему вы вообще ведете речь о "underflow или overflow для int"? Приведения типов (между signed и unsigned) никогда не вызывали "переполнений" в С и С++. Как я сказал выше, приведение от signed к unsigned определено стандартом. Приведение от unsigned к signed всегда было implementation defined, но сейчас стандарты С и С++ четко определяют и его тоже. При целочисленном приведении нет никакого "underflow или overflow для int" даже отдаленно. "Overflow для int" существует только в процессе выполнения арифметических операций над int, но не в процессе выполнения приведений. Так что к чему вы вообще приплели тут "underflow или overflow для int" — в упор не ясно.


Да, тут я дал маху и перепутал приведение типов и переполнение при арифметических операциях. В ОП, конечно же, речь шла о приведении типов.
Re[3]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 09:58
Оценка: :)
Здравствуйте, netch80, Вы писали:

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


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


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

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

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

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

Так что нет, индексы и размеры должны быть знаковыми и только знаковыми.
Re[8]: Коды ошибок и отрицательные числа
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.01.22 10:49
Оценка: +1
Здравствуйте, T4r4sB, Вы писали:

M>>

M>> v[i-1]...
M>>[/ccode]
TB>Костыль, уродливый костыль



Ну, лови тогда так:
for (size_t i=v.size(); i--; )
{
    std::cout << v[i] << " ";
}
Маньяк Робокряк колесит по городу
Re[2]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 11:27
Оценка: :)
Вопрос всем, кто пишет, что "err != 0xFFFFFFFFFFFFFFFF" просто и понятно как дважды-два:

Вы проверяете чужой код, видите следующий кусок:
nread = my_read(...)
if (nread == 0xFFFFFFFFFFFFFFFF)
    throw;
my_copy(src, dst, nread);



Ваши действия? Только я попрошу рассмотреть все возможные случаи, а не тот, где вы наизусть знаете кодовую базу. И если ответ будет "пойду смотреть, что там может вернуть my_read()", то это, конечно, корректный ответ, но далеко так не уехать, потому что my_read легко может стать my_fucking_long_func размером строчек 500. Или вообще не иметь исходного кода и, например, линковаться на последнем этапе или подтягиваться из сгенерированных исходников.

P.S. Да, я последнее время как-то увлёкся темой mission critical, формальными доказательствами и прочей, неинтересной в нормальном мире ерундой. Но это не делает мои аргументы бессмысленными. Почитайте, хотя бы, блог PVS-Studio и ужаснитесь количеству глупых ошибок в крупных открытых проектах, которые, очевидно, попали в мастер по недоглядке.
Re[7]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.02.22 08:04
Оценка: +1
Здравствуйте, Don Reba, Вы писали:

M>>>Поэтому надо просто писать

M>>>
M>>>for(auto i=0u; i!=v.size(); ++i)
M>>>


N>>А теперь повторите это для прохождения по элементам в порядке убывания индексов.


DR>
DR>for (auto i = v.size(); i --> 0;)
DR>


Да, знаменитый приём (и я его рядом упоминал). Но уже с хаком в виде постинкремента, и конструкция цикла тут совсем другая, и безусловный переход из 0 в (size_t)-1 это некрасиво и в общем случае непереносимо. Автоматически до него ~99% пишущих не додумаются, это надо видеть. Вместо него, скорее всего, будет сделан цикл с постпроверкой.
Итого — совсем не эквивалент.
The God is real, unless declared integer.
Re[5]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 01.02.22 17:32
Оценка: :)
Здравствуйте, sergii.p, Вы писали:

SP>уж что-что, но это не обычный заголовок. В данном случае .. в терминах математики означает [0; v.len()-1). Последний элемент не включается. То есть вы ещё один элемент откусили от вектора.


Всё верно, мне надо перебрать все элементы кроме последнего. И почему в этом "безопасном" языке даже такая простая конструкция скрывает в себе проблемы?

SP>Вообще циклы добавили в раст для выявления профнепригодности. Итераторы же есть.


Ах, ну да, я же забыл, пенсионерские отсталые циклы уже не в моде в этом сезоне, сейчас модная прогрессивная молодёжь использует клёвые весёлые итераторы.
Вот только индексация универсальнее итератора, и оптимизируется лучше.
Re[4]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 01.02.22 17:37
Оценка: +1
Здравствуйте, 5.März, Вы писали:

5M>В дотнете и тысяче других более-менее новых языков тоже все размеры и индексы знаковые


Но комитет Раста решил всё сделать через жопу
Re[11]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.02.22 09:34
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, Sinclair, Вы писали:


АТ>>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>>И каков же в нашем мире результат вычитания 8 из 5?
BFE>В реальном мире = 0. С оговоркой, что 0 — это пусто.

Точно не ноль. Скорее — исключение по невозможности совершить операцию.

BFE>В мире идей = -3.

BFE>Выберите свой мир.

Ваша вселенная удивительна, но людям там слегка не место.
The God is real, unless declared integer.
Re[11]: Коды ошибок и отрицательные числа
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.22 12:02
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, Sinclair, Вы писали:


АТ>>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>>И каков же в нашем мире результат вычитания 8 из 5?
BFE>В реальном мире = 0. С оговоркой, что 0 — это пусто.
Ну, то есть в вашем реальном мире 5-8 == 7-8, я правильно понимаю? А 10 + (5-7) и 10 + (7-8) тоже будут равны между собой?
Занятная алгебра у вас там, в "реальном мире".
BFE>В мире идей = -3.
BFE>Выберите свой мир.
.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[12]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 02.02.22 14:26
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

АТ>>>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>>>И каков же в нашем мире результат вычитания 8 из 5?
BFE>>В реальном мире = 0. С оговоркой, что 0 — это пусто.
S>Ну, то есть в вашем реальном мире 5-8 == 7-8, я правильно понимаю? А 10 + (5-7) и 10 + (7-8) тоже будут равны между собой?
S>Занятная алгебра у вас там, в "реальном мире".

А то! Смотрите, что пишет T4r4sB
Автор: T4r4sB
Дата: 01.02.22
:

Ээээ, вообще-то [0, -1), и [0, -2) тоже — это пустой диапазон

Отрицание существования отрицательных чисел интуитивно согласуется с этим утверждением.
Ну, а если вы думаете, что отрицательные числа существуют, то покажите мне минус пять яблок. Именно яблок, а не их огрызков.

BFE>>В мире идей = -3.

BFE>>Выберите свой мир.
S>.

На дворе коронавирус, а вы себя за лицо хватаете...
Числа — это всё условности:
for(unsigned i = 2; i != -4; --i)
  std::cout << i << std::endl;

2
2
1
0

4294967295
4294967294
4294967293
И каждый день — без права на ошибку...
Re[10]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 02.02.22 17:28
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>И каков же в нашем мире результат вычитания 8 из 5?

В мире количественных вычислений не бывает не только "результата вычитания 8 из 5", но не бывает даже и необходимости вычитать 8 из 5. Возникновение такой необходимости в каких-либо выкладках — это звоночек, говорящий, что где-то раньше вы совершили ошибку и забрели не в ту степь.

Это примерно как спрашивать, чему равна сумма трех авторучек и пяти литров чернил.
Best regards,
Андрей Тарасевич
Re: Коды ошибок и отрицательные числа
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.01.22 07:04
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Никак не могу сопоставить в голове кое-что про коды ошибок. Со времён юникса тянется наследие в виде отрицательных значений при возврате кода ошибки целочисленным числом. Очевидно, что писать повсюду "err != -1" не очень-то приятно.


Зато писать "err<0" вполне приятно.

C>Поэтому возникла мысль, что результат сохраняли в unsigned и вместо этого писали "err < INT_MAX", что читается легче и понятнее. НО! С тех же самых бородатых времён тянется наследие в виде уникальных платформ, про которые никто не слышал, правда, где underflow или overflow для int НЕ выполняется циклически,


Причем тут уникальность каких платформ? Такое на любой платформе можно получить довольно легко


C>и таким образом приведение int к unsingned для отрицательных чисел считается UB (слышал, что хотят отменить).


Где ты такое вычитал?


C>А ведь как было бы приятно жить в мире доминирования неотрицательных чисел? Ошибки тогда просто уходили бы в INT_MAX, а используемый диапазон сокращался бы не вполовину, а всего на несколько элементов. Реально целые отрицательные используются для отрицательных смещений, разности двух величин и ... всё


Очень неудачное решение.
Можно возвращать не просто -1, а отрицательный код ошибки, вместо сохранения его в errno, например.
У меня есть самописные контейнеры, например, кольцевой буфер, там тип размера — параметр шаблона, и я могу использовать uint8_t/uint16_t для экономии памяти, а для инвалидного индекса есть npos.
Маньяк Робокряк колесит по городу
Re: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 07:10
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Никак не могу сопоставить в голове кое-что про коды ошибок. Со времён юникса тянется наследие в виде отрицательных значений при возврате кода ошибки целочисленным числом. Очевидно, что писать повсюду "err != -1" не очень-то приятно. Поэтому возникла мысль, что результат сохраняли в unsigned и вместо этого писали "err < INT_MAX", что читается легче и понятнее. НО! С тех же самых бородатых времён тянется наследие в виде уникальных платформ, про которые никто не слышал, правда, где underflow или overflow для int НЕ выполняется циклически, и таким образом приведение int к unsingned для отрицательных чисел считается UB (слышал, что хотят отменить).


Какая-то непонятная чепуха написана.

Во-первых, поведение целочисленных типов при приведении от signed к unsigned четко определено стандартом языка. Никаких неожиданностей здесь нет и никакого "наследия уникальных платформ" нет тоже. Если вам нравится сохранять результат в `unsigned` и проверять на `err < INT_MAX` — флаг вам в руки. Возможно тут есть какие-то подводные камни, но в общем и целом это будет гарантированно работать. Почему вы считаете, что это "лучше" проверки на отрицательность, я в упор не вижу, но если вам так больше нравится — вперед.

Во-вторых, возвращаясь к вопросу знакового переполнения ("для int"), о каких "уникальных платформах" вы ведете речь? Вы о чем вообще? Постарайтесь понять простую вещь: основным источником неопределенного поведения в С и С++ является не аппаратная платформа, а компилятор. Компилятор, компилятор и только компилятор. То есть те предположения о "невозможности" неопределенного поведения, которые он широко, охотно и активно использует в процессе оптимизации кода. Неопределенное поведение в С и С++ существует именно для этого: чтобы помочь компилятору в оптимизации кода. На всех С и С++ платформах, без единого исключения, знаковые типы НЕ заворачиваются при переполнении. Никакой "уникальности" или "бородатости" в этом нет. Что за чушь? Ни на одной современной С или С++ платформе `int` НЕ заворачивается. С/С++ платформ с заворачивающимся `int` не существует и не существовало нигде и никогда, кроме, возможно, вашего воображения. Ни "уникальных", ни "повсеместных", ни "бородатых", ни "бритых" — никаких.

В-третьих, почему вы вообще ведете речь о "underflow или overflow для int"? Приведения типов (между signed и unsigned) никогда не вызывали "переполнений" в С и С++. Как я сказал выше, приведение от signed к unsigned определено стандартом. Приведение от unsigned к signed всегда было implementation defined, но сейчас стандарты С и С++ четко определяют и его тоже. При целочисленном приведении нет никакого "underflow или overflow для int" даже отдаленно. "Overflow для int" существует только в процессе выполнения арифметических операций над int, но не в процессе выполнения приведений. Так что к чему вы вообще приплели тут "underflow или overflow для int" — в упор не ясно.
Best regards,
Андрей Тарасевич
Отредактировано 30.01.2022 7:17 Андрей Тарасевич . Предыдущая версия . Еще …
Отредактировано 30.01.2022 7:16 Андрей Тарасевич . Предыдущая версия .
Отредактировано 30.01.2022 7:14 Андрей Тарасевич . Предыдущая версия .
Re: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 07:22
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Никак не могу сопоставить в голове кое-что про коды ошибок. Со времён юникса тянется наследие в виде отрицательных значений при возврате кода ошибки целочисленным числом. Очевидно, что писать повсюду "err != -1" не очень-то приятно. Поэтому возникла мысль, что результат сохраняли в unsigned и вместо этого писали "err < INT_MAX", что читается легче и понятнее.


Нет, не писали. Нет, не понятнее.
И это только в ядерном API возврат -1 для всех ошибок. Есть такие, в которых -1, -2, ...
Поэтому "< 0" универсальнее.

C> НО! С тех же самых бородатых времён тянется наследие в виде уникальных платформ, про которые никто не слышал, правда, где underflow или overflow для int НЕ выполняется циклически, и таким образом приведение int к unsingned для отрицательных чисел считается UB (слышал, что хотят отменить).


C++20 — уже отменили. C — на очереди.
Разница между ==1 и <0 при единственном -1 тут не появляется. А вот подозрительные конверсии — не в тему.

C>А ведь как было бы приятно жить в мире доминирования неотрицательных чисел? Ошибки тогда просто уходили бы в INT_MAX, а используемый диапазон сокращался бы не вполовину, а всего на несколько элементов. Реально целые отрицательные используются для отрицательных смещений, разности двух величин и ... всё


И это будет решение частного случая, а не общего подхода, причём предельно кривым методом.
Вы не хотите взглянуть чуть-чуть шире. На самом деле у этих функций не какие-то -1 или прочее, это уже результат укладки в доступные (для дорогого хардвера 1970-х) возможности. Все эти функции, по сути, возвращают то, что в C++ называется variant, в Rust — enum:

enum errno { коды; };
struct normal_rvalue { int v; };
using syscall_retval = std::variant<normal_rvalue, errno>;


enum syscall_retval {
  normal(int),
  error(errno),
}


Это и отражается соответственно в ядерном ABI. Например, FreeBSD на x86 использует такое: если при выходе из сисколла CF=0, то в EAX/RAX нормальное значение, оно и передаётся. Если CF=1, то RAX пишется в errno текущей нити и заменяется на -1.

Ряд более новых функций, типа семейства pthread_*, возвращают 0 нормально и код errno в случае ошибки, там такого костыля, как выше, нет.

А вот если бы такой variant был в явном виде с самого начала — вы бы это и проверяли по типу (псевдокод):

match open("/dev/null", O_RDONLY) {
  case normal_rvalue(int newfd): ...
  case error(int err): ...


c> А ведь как было бы приятно жить в мире доминирования неотрицательных чисел?


Рядом хорошо расписали, чем это плохо.
The God is real, unless declared integer.
Re[2]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 07:44
Оценка:
Здравствуйте, netch80, Вы писали:

N>C++20 — уже отменили. C — на очереди.


UB при signed overflow никто в С++20 не отменял. То, что signed overflow на самом деле не имеет никакого отношения к теме, поднятой автора вопроса — дело другое, но тем не менее....
Best regards,
Андрей Тарасевич
Re[3]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 07:53
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, netch80, Вы писали:


N>>C++20 — уже отменили. C — на очереди.


АТ>UB при signed overflow никто в С++20 не отменял. То, что signed overflow на самом деле не имеет никакого отношения к теме, поднятой автора вопроса — дело другое, но тем не менее....


Спасибо за уточнение. Я "отменили" написал к словам комментатора

C>> НО! С тех же самых бородатых времён тянется наследие в виде уникальных платформ, про которые никто не слышал, правда, где underflow или overflow для int НЕ выполняется циклически


но получилось недостаточно явно, к чему это было.
The God is real, unless declared integer.
Re[2]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 09:38
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

AT>На всех С и С++ платформах, без единого исключения, знаковые типы НЕ заворачиваются при переполнении. Никакой "уникальности" или "бородатости" в этом нет. Что за чушь? Ни на одной современной С или С++ платформе `int` НЕ заворачивается. С/С++ платформ с заворачивающимся `int` не существует и не существовало нигде и никогда, кроме, возможно, вашего воображения. Ни "уникальных", ни "повсеместных", ни "бородатых", ни "бритых" — никаких.


`gcc -fwrapv`, `clang -fwrapv` это столь же законные и легкодоступные платформы, как и просто `gcc` или `clang`, почти повсеместные, и они именно "с заворачивающимся `int`". Зачем вы говорите про их несуществование, да ещё и с таким апломбом, мне непонятно.
И оно реально используется: CPython2 компилируется именно с -fwrapv (при том, что с -O3). (В 3-м это устранили — видно, вычистили проблемные места.)

Разумеется, имеет смысл дописать, что использовать такое плохо (некошерно, некузяво и т.п.), но это не вопрос формальной возможности.

AT> Приведение от unsigned к signed всегда было implementation defined, но сейчас стандарты С и С++ четко определяют и его тоже.


И где такое сказано для C?

C17 (N2176) и последний на сейчас драфт (N2731), 6.3.1.3(3):

Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.


AT>При целочисленном приведении нет никакого "underflow или overflow для int" даже отдаленно.


Как же нет, если аргумент не вмещается в область значений результата.
Может, вам не нравится слово "переполнение" для этого, но это синоним де факто.

То, что большинство компиляторов реализуют его как bit cast, это таки I-D. Сами ж хотели все платформы, а не только основные.

АТ>Какая-то непонятная чепуха написана.


The God is real, unless declared integer.
Re[2]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 30.01.22 09:47
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Отрицательные пиксельные координаты — повсюду.


Экранные? Это где, например? Графику мы не берём, там сразу floating-point.
Re: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 09:51
Оценка:
Здравствуйте, cppguard, Вы писали:

C>А ведь как было бы приятно жить в мире доминирования неотрицательных чисел?


Я уже несколько лет адово бомблю про идиотим с беззнаковым размером и индексом у векторов.
Заведи же блин именованную константу для этой своей -1.
Re[2]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 09:53
Оценка:
Здравствуйте, 5.März, Вы писали:

5M>Signed и unsigned следуют разной арифметике: signed представляет обычные числа которые следуют обычной арифметике в которой x-1 < x всегда true (именно из-за этого signed underflow/overflow навсегда объявлено UB)


И это большая проблема С/С++ — нет стандартного способа проверить, что у тебя всё ок с арифметикой, потому что компилятор тупо вырезает проверки вида assert(a+b>a). Если бы в стандарте был описан отладочный режим, при котором переполнение знаковых это остановка программы и вызов отладчика / завершение программы, то было бы всё не так плохо, но такой режим есть только в виде личной инициативы отдельных компиляторов.
Re[2]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 09:58
Оценка:
Здравствуйте, AeroSun, Вы писали:

AS>Подведу итог:


Много берёте на себя, и в принципиальных моментах неверно.

AS>3) всегда сравнение было с нулём, причем 0 — это всё ок, -1 — это невалидное значение, 1+ — это коды ошибок


НЕТ.

Если говорить в контексте типового Unix API, то есть минимум 4 разных случая:

1. Нет ошибки — 0, ошибка — -1 и в errno сохранён код ошибки (>0).
Выполняется для функций, у которых только признак успех/неудача (как close(), ioctl(), setuid()...), или результат идёт другим каналом (указатель в аргументах, например: pipe() — массив на 2 дескриптора).

2. Нет ошибки — >=0, ошибка — -1 и в errno сохранён код ошибки (>0). Это open(), read(), write(), fcntl() и десятки других.

3. Нет ошибки — 0, ошибка — код ошибки больше 0, обычно из errno. Результат всегда идёт другим каналом (по указателю в аргументах). Это вся группа pthread_*, это getaddrinfo(), getnameinfo() и некоторые другие.

(Кстати, если ошибки нет, варианты 1-3 могут менять errno, а могут и не менять.)

4. Индикации ошибки в возвращаемом значении нет вообще (или слишком много вариантов). Для проверки на ошибку надо смотреть на errno (предварительно обнулив его) и на другие признаки.
Пример: strtol(): если значение вышло за пределы — она пишет ERANGE в errno. Если после числа в строке мусор — надо смотреть на *endptr != 0. Если на входе пустая строка — ответ 0, errno == 0, но факт пустой строки определяется по endptr == beginptr.

А вот варианта, что вы описали, именно в этой комбинации, просто не существует.

AS>1) в стартовом посте написан сумбур


Топикстартер хотел разобраться. Как известно, чтобы получить ответ, надо в вопросе сформулировать его половину. Сумбур — не страшно, главное — ключевые слова.

AS>2) никто ничего не сохранял в unsigned


Тут единственное что верно, с поправкой на то, что на уровне ассемблера могли вообще не смотреть на знак.

AS>4) уже давно вместо этого используют typed enum — чего и вам советую


Перевести на него существующее API пока как-то невозможно.
The God is real, unless declared integer.
Отредактировано 30.01.2022 10:06 netch80 . Предыдущая версия .
Re[2]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 30.01.22 09:59
Оценка:
Здравствуйте, AeroSun, Вы писали:


AS>Подведу итог:

AS>1) в стартовом посте написан сумбур
Лишь толко часть, где я спутал переполнение и приведение.

AS>2) никто ничего не сохранял в unsigned

Да, об этом-то и речь. Почему?

AS>3) всегда сравнение было с нулём, причем 0 — это всё ок, -1 — это невалидное значение, 1+ — это коды ошибок

Если код, например, для автопилота, то нужно будет обработать -2, даже если оно там не планируется. Или доказать, что -2 не появится ни при каких условиях, что сделать труднее. Symbolic execution становится сложнее.

AS>4) уже давно вместо этого используют typed enum — чего и вам советую

Я вообще не пишу на С++
Re[3]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 10:07
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Экранные? Это где, например? Графику мы не берём, там сразу floating-point.


Да хотя бы положение гуи-элемента на экране.
Re[4]: Коды ошибок и отрицательные числа
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.01.22 10:15
Оценка:
Здравствуйте, T4r4sB, Вы писали:

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

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

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


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


Поэтому надо просто писать
for(auto i=0u; i!=v.size(); ++i)
Маньяк Робокряк колесит по городу
Re[4]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 10:20
Оценка:
Здравствуйте, 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 оно не хочет из-за этого создавать просто пустое множество...)
The God is real, unless declared integer.
Отредактировано 30.01.2022 10:38 netch80 . Предыдущая версия .
Re[5]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 10:21
Оценка:
Здравствуйте, Marty, Вы писали:

M>Поэтому надо просто писать

M>
M>for(auto i=0u; i!=v.size(); ++i)
M>


А теперь повторите это для прохождения по элементам в порядке убывания индексов.
The God is real, unless declared integer.
Re[3]: Коды ошибок и отрицательные числа
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 30.01.22 10:25
Оценка:
Здравствуйте, cppguard, Вы писали:

N>>Отрицательные пиксельные координаты — повсюду.


C>Экранные? Это где, например? Графику мы не берём, там сразу floating-point.


Не экранные, а на картинке. Сдвигаешь что-нибудь и оно выходит за пределы кадра или карты. Объект детектируется нейросеткой у края, особенно если часть его уже вышла за пределы — сразу или в минус, или в плюс за кадр.
Картинку повернул н какой-то угол — края уже не поместились.
Отредактировано 30.01.2022 10:26 Nuzhny . Предыдущая версия .
Re[3]: Коды ошибок и отрицательные числа
От: σ  
Дата: 30.01.22 10:26
Оценка:
5M>>Signed и unsigned следуют разной арифметике: signed представляет обычные числа которые следуют обычной арифметике в которой x-1 < x всегда true (именно из-за этого signed underflow/overflow навсегда объявлено UB), unsigned представляет машинные слова которые следуют modulo-2^N арифметике, где x-1 может быть как меньше так и больше x (well-defined)

N>Нет, это вы приводите как раз позднюю _ре_интерпретацию подхода, которая возникла по сути из-за хакерского переиспользования недостаточно строгих правил предшествующих стандартов.


Поздняя — это когда? Предшествующие стандарты — это какие?
Re[5]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 10:26
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, T4r4sB, Вы писали:


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


M>Поэтому надо просто писать

M>
M>for(auto i=0u; i!=v.size(); ++i)
M>

Это другой код. Для тех, кто не знает синтаксис Раста — интервалы вида a..b там полуоткрытые.
Re[4]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 10:31
Оценка:
Здравствуйте, σ, Вы писали:

5M>>>Signed и unsigned следуют разной арифметике: signed представляет обычные числа которые следуют обычной арифметике в которой x-1 < x всегда true (именно из-за этого signed underflow/overflow навсегда объявлено UB), unsigned представляет машинные слова которые следуют modulo-2^N арифметике, где x-1 может быть как меньше так и больше x (well-defined)


N>>Нет, это вы приводите как раз позднюю _ре_интерпретацию подхода, которая возникла по сути из-за хакерского переиспользования недостаточно строгих правил предшествующих стандартов.


σ>Поздняя — это когда? Предшествующие стандарты — это какие?


1990-е и позже. Примерно тогда, когда начали использовать оптимизации, описанные Мучником (могут быть и другие источники, но его книга самая показательная).

Предшествующие это ANSI 1985-го года (первый который был вообще стандартом за пределами Bell Labs) и ISO 1989-го.
The God is real, unless declared integer.
Re[5]: Коды ошибок и отрицательные числа
От: σ  
Дата: 30.01.22 10:35
Оценка:
5M>>>>Signed и unsigned следуют разной арифметике: signed представляет обычные числа которые следуют обычной арифметике в которой x-1 < x всегда true (именно из-за этого signed underflow/overflow навсегда объявлено UB), unsigned представляет машинные слова которые следуют modulo-2^N арифметике, где x-1 может быть как меньше так и больше x (well-defined)

N>>>Нет, это вы приводите как раз позднюю _ре_интерпретацию подхода, которая возникла по сути из-за хакерского переиспользования недостаточно строгих правил предшествующих стандартов.


σ>>Поздняя — это когда? Предшествующие стандарты — это какие?


N>1990-е и позже. Примерно тогда, когда начали использовать оптимизации, описанные Мучником (могут быть и другие источники, но его книга самая показательная).


N>Предшествующие это ANSI 1985-го года (первый который был вообще стандартом за пределами Bell Labs) и ISO 1989-го.


В ANSI C89 Rationale написано, что unsigned это неудачное название для модульной арифметики. Не очень похоже на "более позднюю реинтерпретацию"
Re[6]: Коды ошибок и отрицательные числа
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.01.22 10:38
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, Marty, Вы писали:


M>>Поэтому надо просто писать

M>>
M>>for(auto i=0u; i!=v.size(); ++i)
M>>


N>А теперь повторите это для прохождения по элементам в порядке убывания индексов.


for(auto i=v.size(); i!=0; --i)
    v[i-1]...
Маньяк Робокряк колесит по городу
Re[7]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 10:39
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну тогда, извините, вы скорее всего ССЗБ, что не сделали проверку на непустоту массива,


А зачем её делать-тоааа?! На знаковых индексах я получал бы 100% валидный код, который на пустом массиве бы ничего не делал, что тут плохого? Почему этот беззнаковый дебилизм вынуждает меня усложнять код?!
Re[6]: Коды ошибок и отрицательные числа
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.01.22 10:39
Оценка:
Здравствуйте, T4r4sB, Вы писали:


TB>Это другой код. Для тех, кто не знает синтаксис Раста — интервалы вида a..b там полуоткрытые.


Твой код на расте проходит по всем элементам, кроме последнего, я правильно понял?
Маньяк Робокряк колесит по городу
Re[7]: Коды ошибок и отрицательные числа
От: σ  
Дата: 30.01.22 10:45
Оценка:
M> v[i-1]...
  Скрытый текст
https://www.youtube.com/watch?v=Y7uKmQS__jc
Re[9]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 10:54
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну, лови тогда так:


Не лучше

Вот так правильно:
for (auto i = v.ssize()-1; i>=0; --i)

Но это только с ssize работает
Re[10]: Коды ошибок и отрицательные числа
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.01.22 10:55
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Не лучше


TB>Вот так правильно:

TB>
TB>for (auto i = v.ssize()-1; i>=0; --i) 
TB>


Не вижу никаких преимуществ
Маньяк Робокряк колесит по городу
Re[6]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 10:59
Оценка:
Здравствуйте, σ, Вы писали:

σ>>>Поздняя — это когда? Предшествующие стандарты — это какие?


N>>1990-е и позже. Примерно тогда, когда начали использовать оптимизации, описанные Мучником (могут быть и другие источники, но его книга самая показательная).


N>>Предшествующие это ANSI 1985-го года (первый который был вообще стандартом за пределами Bell Labs) и ISO 1989-го.


σ>В ANSI C89 Rationale написано, что unsigned это неудачное название для модульной арифметики. Не очень похоже на "более позднюю реинтерпретацию"


Скачал один похожий документ (от 1988). Вижу пассаж:

The keyword unsigned is something of a misnomer, suggesting as it does arith-
metic that is non-negative but capable of overflow. The semantics of the C type
unsigned is that of modulus, or wrap-around, arithmetic, for which overflow has
no meaning. The result of an unsigned arithmetic operation is thus always defined,
whereas the result of a signed operation may (in principle) be undefined. In prac-
tice, on twos-complement machines, both types often give the same result for all
operators except division, modulus, right shift, and comparisons. Hence there has
been a lack of sensitivity in the C community to the differences between signed and
unsigned arithmetic (see §3.2.1.1).


Вы про него?
OK, тогда хронологию надо чуть сдвинуть. К 85-му это ещё толком не поняли. Это Rationale, как видно, от 88-го. Разница в 4 года по сравнению со стартом C (1970-е) несущественна. Спасибо, документ сохраню — как-то я его пропустил.

Но вот последнее предложение цитаты показывает, что окончательного решения по поводу, что делать со знаковой арифметикой, не было. Это основное, на что я тут намекал. Именно в промежутке между C89 и C99 сформировалась идея абьюза предыдущей зависимости от представления отрицательных — совсем не под то, из чего она возникла.

Там ещё интересно про споры про вариант integral promotion (расширять до signed или unsigned?) на страницах 34-35.
The God is real, unless declared integer.
Re[8]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 11:08
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, netch80, Вы писали:


N>>Ну тогда, извините, вы скорее всего ССЗБ, что не сделали проверку на непустоту массива,


TB>А зачем её делать-тоааа?! На знаковых индексах я получал бы 100% валидный код, который на пустом массиве бы ничего не делал, что тут плохого? Почему этот беззнаковый дебилизм вынуждает меня усложнять код?!


Я полностью согласен, что был бы "100% валидный код, который на пустом массиве бы ничего не делал".

Я не согласен, что в этом случае вообще в этот код надо как-то входить. Задача, где пропускается последний элемент, при пустом массиве означает (практически наверняка) вообще некорректную постановку, если этот массив законный, или нарушение в данных. Мой комментарий был исключительно об этом.

И поэтому плохо приводить её как пример.

Пример с перебором назад, который я упоминал, и который обсуждался в прошлой дискуссии, тут лучше. Если у вас N элементов с нумерацией от 0 до N-1, то цикл вида

for (unsigned i = N-1; i >= 0; --i) {
  ...
}


некорректен — нужно или менять на пост-проверку, или постинкремент (знаменитый хак), или на знаковые. Сама же задача так пройтись по элементам не имеет никакой проблемы в постановке.
The God is real, unless declared integer.
Re[9]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 11:11
Оценка:
Здравствуйте, netch80, Вы писали:

N>Я не согласен, что в этом случае вообще в этот код надо как-то входить. Задача, где пропускается последний элемент, при пустом массиве означает (практически наверняка) вообще некорректную постановку, если этот массив законный, или нарушение в данных. Мой комментарий был исключительно об этом.


Ну, это не так. Взять тот же случай, когда надо перебрать пары элементов.
Re: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 30.01.22 11:25
Оценка:
Здравствуйте, cppguard, Вы писали:

Вопрос всем, кто пишет, что "err != -1" просто и понятно как дважды-два:

Вы проверяете чужой код, видите следующий кусок:
nread = my_read(...)
if (nread == -1)
    throw;
my_copy(src, dst, nread);


Ваши действия? Только я попрошу рассмотреть все возможные случаи, а не тот, где вы наизусть знаете кодовую базу. И если ответ будет "пойду смотреть, что там может вернуть my_read()", то это, конечно, корректный ответ, но далеко так не уехать, потому что my_read легко может стать my_fucking_long_func размером строчек 500. Или вообще не иметь исходного кода и, например, линковаться на последнем этапе или подтягиваться из сгенерированных исходников.

P.S. Да, я последнее время как-то увлёкся темой mission critical, формальными доказательствами и прочей, неинтересной в нормальном мире ерундой. Но это не делает мои аргументы бессмысленными. Почитайте, хотя бы, блог PVS-Studio и ужаснитесь количеству глупых ошибок в крупных открытых проектах, которые, очевидно, попали в мастер по недоглядке.
Re[2]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 17:42
Оценка:
Здравствуйте, 5.März, Вы писали:

5M>B.Stroustrup “Subscripts and sizes should be signed”: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf


Это один из хороших примеров "Страуструпа несущего чушь". К сожалению, под видом натягивания этой знаковой совы на глобус `std::span` он одновременно пытается натянуть эту сову на весь язык.
Best regards,
Андрей Тарасевич
Re[2]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 18:05
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Ваши действия? Только я попрошу рассмотреть все возможные случаи, а не тот, где вы наизусть знаете кодовую базу. И если ответ будет "пойду смотреть, что там может вернуть my_read()", то это, конечно, корректный ответ, но далеко так не уехать, потому что my_read легко может стать my_fucking_long_func размером строчек 500. Или вообще не иметь исходного кода и, например, линковаться на последнем этапе или подтягиваться из сгенерированных исходников.


Есть документация. Может, в doxygen/аналоге. Может, отдельно. Но корректность этой документации и соответствие кода описанию в ней — вопрос качества сопровождения кода.

Мы в очень многом полагаемся на это качество, начиная вообще с качества выполнения команд процессором. Я не вижу тут пути кроме как "доверяй, но проверяй". Разумеется, если есть методы автоматизированной верификации — их не стоит избегать.

C>P.S. Да, я последнее время как-то увлёкся темой mission critical, формальными доказательствами и прочей, неинтересной в нормальном мире ерундой. Но это не делает мои аргументы бессмысленными. Почитайте, хотя бы, блог PVS-Studio и ужаснитесь количеству глупых ошибок в крупных открытых проектах, которые, очевидно, попали в мастер по недоглядке.


Да. И всё равно всё, насколько я представляю себе, проверить можно только в очень ограниченном наборе верифицируемых окружений.

И должен заметить, что я не понимаю, как это связано с исходной темой.
The God is real, unless declared integer.
Re[3]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 18:34
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

5M>>B.Stroustrup “Subscripts and sizes should be signed”: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf


АТ>Это один из хороших примеров "Страуструпа несущего чушь". К сожалению, под видом натягивания этой знаковой совы на глобус `std::span` он одновременно пытается натянуть эту сову на весь язык.


Он совершенно правильно ставит проблему. Плохо только то, что любое качественное решение проблемы означает новый язык без обратной совместимости
The God is real, unless declared integer.
Re[3]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 18:34
Оценка:
Здравствуйте, netch80, Вы писали:

AT>> Приведение от unsigned к signed всегда было implementation defined, но сейчас стандарты С и С++ четко определяют и его тоже.


N>И где такое сказано для C?


Я даже удивился, что для придирки к этому утверждению понадобилось столько времени Ждал.

Все, я думаю, поняли, что под "сейчас" я имею в виду то, что отказ от формальной поддержки 1's-complement и sign-and-magnitude платформ — вопрос уже решенный и согласованный между С и С++. Просто считайте, что эта часть уже опубликованного стандарта С++ распространяется и на С тоже.
Best regards,
Андрей Тарасевич
Re[4]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 19:08
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

AT>>> Приведение от unsigned к signed всегда было implementation defined, но сейчас стандарты С и С++ четко определяют и его тоже.


N>>И где такое сказано для C?


АТ>Я даже удивился, что для придирки к этому утверждению понадобилось столько времени Ждал.


Больше времени, чем ожидалось — ни о чём. Меньше — может что-то показать, больше — нет.

АТ>Все, я думаю, поняли, что под "сейчас" я имею в виду то, что отказ от формальной поддержки 1's-complement и sign-and-magnitude платформ — вопрос уже решенный и согласованный между С и С++. Просто считайте, что эта часть уже опубликованного стандарта С++ распространяется и на С тоже.


Позиция понятна и с таким пояснением о планах и согласованиях я безусловно согласен. Тем не менее, поскольку дословно сказано было о "стандартах" и "чётко определяют", то утверждение неверно.
The God is real, unless declared integer.
Re[10]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 19:13
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, netch80, Вы писали:


N>>Я не согласен, что в этом случае вообще в этот код надо как-то входить. Задача, где пропускается последний элемент, при пустом массиве означает (практически наверняка) вообще некорректную постановку, если этот массив законный, или нарушение в данных. Мой комментарий был исключительно об этом.


TB>Ну, это не так. Взять тот же случай, когда надо перебрать пары элементов.


Хм, ну предположим. Хотя я с ходу не вижу вариантов применения кроме, простите, сортировки пузырьком — случай редкий и почти бесполезный. Или проверки сортированности массива (зачем?) — то же самое, вид сбоку. Для них, да, пустой массив — законный вариант.
Тогда таки можно считать не [0..len-1), а [1..len) (хм, Marty по сути предлагал то же самое?)

В любом случае, повторюсь, я поддерживаю, что в общем и целом со знаковыми удобнее хотя бы тем, что не надо следить за возможными проблемами перехода 0 -> 0-1. Вопрос был в конкретном примере.
The God is real, unless declared integer.
Re[11]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 19:41
Оценка:
Здравствуйте, netch80, Вы писали:

N>Тогда таки можно считать не [0..len-1), а [1..len) (хм, Marty по сути предлагал то же самое?)


Да, можно просто переписать перебор таким способом. А если надо обойти с конца, то надо просто переписать перебор ещё другим способом. А если надо что-то ещё сделать, то можно просто переписать алгоритм ещё каким-то способом. А если нужен вот такой вот алгоритм, то для него можно просто переписать не так, а вот так. А если нужен такой случае, то можно просто переписать ещё как-то вот так.
И всё это говноедство обусловлено не реальной причиной, а абсолютно надуманной. Просто кто-то не подумал головой.

N>В любом случае, повторюсь, я поддерживаю, что в общем и целом со знаковыми удобнее хотя бы тем, что не надо следить за возможными проблемами перехода 0 -> 0-1. Вопрос был в конкретном примере.


Ну может перебор отрезков ломаной, заданной в виде массива опорных точек, я не говорю, что вариант офигеть какой жизненный.
Re[12]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 30.01.22 20:09
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Она распространяется не только на беззнаковые типы, но и на указательную арифметику, на итераторы, на потоки и на массу других концепций боле высокого уровня.


И как же сложить два итератора? Или два потока?
Индекс можно являться участником арифметических выражений (и является), а итератор, ну разве что в a-b, и то только для векторов.
Re[3]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 30.01.22 22:56
Оценка:
Здравствуйте, netch80, Вы писали:

N>Есть документация. Может, в doxygen/аналоге. Может, отдельно. Но корректность этой документации и соответствие кода описанию в ней — вопрос качества сопровождения кода.


N>Мы в очень многом полагаемся на это качество, начиная вообще с качества выполнения команд процессором. Я не вижу тут пути кроме как "доверяй, но проверяй". Разумеется, если есть методы автоматизированной верификации — их не стоит избегать.


Да, так и делается сейчас, но я этого не понимаю. Ведь куда как легче проверять код типа
unsgined nread = my_read(...)
if (nread < SOME_CONST)
    my_copy(src, dst, nread)
throw io_error(nread);
Re[4]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.01.22 07:55
Оценка:
Здравствуйте, cppguard, Вы писали:

N>>Мы в очень многом полагаемся на это качество, начиная вообще с качества выполнения команд процессором. Я не вижу тут пути кроме как "доверяй, но проверяй". Разумеется, если есть методы автоматизированной верификации — их не стоит избегать.


C>Да, так и делается сейчас, но я этого не понимаю. Ведь куда как легче проверять код типа

C>
C>unsgined nread = my_read(...)
C>if (nread < SOME_CONST)
C>    my_copy(src, dst, nread)
C>throw io_error(nread);
C>


Ну а я не понимаю, что вам непонятно. Какая принципиальная разница между nread != CONST1 и nread < CONST2, если в каждом из этих вариантов сказано, что такая константа единственная, которая означает ошибку, и CONST2 больше всех не-ошибочных значений?
Проверки полностью эквивалентны.
The God is real, unless declared integer.
Re[5]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 31.01.22 08:27
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну а я не понимаю, что вам непонятно. Какая принципиальная разница между nread != CONST1 и nread < CONST2, если в каждом из этих вариантов сказано, что такая константа единственная, которая означает ошибку, и CONST2 больше всех не-ошибочных значений?

N>Проверки полностью эквивалентны.

Разница в том, что в варианте с != если по какой-то причине кроме -1 функция может вернуть -2, то программа будет содержать ошибку. Ещё хуже то, что это неуправляемая память, и ошибка может проявиться как угодно: аварийное завершение, порча стека и т.д. Если же мы проверяем через <, то мы поделили область определения функции на два диапазона. Математически эта функция становится составной функцией вида

{ f(x), x < X; g(x), X <= x; x э Z_uint32 }

и при этом остаётся total function (я не знаю, как по-русски), т.е. определена на всём промежутке значений входного аргумента.

C !=, конечно же, можно добиться аналогичного эффекта, но нужно тогда писать "x < 0", но так мало кто делает, это заметно даже по комментариям.
Re[2]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 31.01.22 09:34
Оценка:
Здравствуйте, 5.März, Вы писали:

Благодарю за хороший, полный ответ, но не согласен с

5M>В 99.99% случаев когда ты размышляешь об операциях с числами, ты и читатели твоего кода подразумевают обычную, а не модульную арифметику


Для меня это не так. Я программист, я пишу программы, программы выполняются на ЭВМ, в ЭВМ целые числа это кольцо по модулю. Скорее, в обратном направлении не всегда удобно думать — что можно сделать и не кольцо, если надо. Но в целом это как с вещественными — сразу в голове держишь конечность представления, двоичные дроби и т.д.

5M>B.Stroustrup “Subscripts and sizes should be signed”: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf


Ну эт классика — дед, который не пишет production ready код, учит нас жизни. "Круче" него только Скотт Мейерс, который вообще программистом не работал. Но в книгах Скотта хотя бы есть толика логики. Страуструпа я тоже уважаю, но правда жизни такова, что можно сколь угодно теоретизировать, а шишки набиваешь только на практике. Да, я в курсе, что он работал в Морган Стэнлей и, может где-то ещё, но мой опыт говорит, что такие мэтры реальный код не пишут, а больше тусуются в каких-нибудь XXX-Core или YYY-Foundation командах или вообще только проводят тренинги в компании.

5M>Длинное видео из 2013г где комитет C++ несколько раз признает ошибочность использования unsigned: https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything (12:10, 42:40, 1:02:50)


Не открывается =(

Я, кстати, больше пишу на Java, чем на Си и С++, и там, как бы, не из чего выбирать. Но если есть выбор, то почему бы им не воспользоваться? Если бы всё так было очевидно, то unsigned давно бы стал deprecated.
Re[6]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.01.22 10:34
Оценка:
Здравствуйте, cppguard, Вы писали:

N>>Ну а я не понимаю, что вам непонятно. Какая принципиальная разница между nread != CONST1 и nread < CONST2, если в каждом из этих вариантов сказано, что такая константа единственная, которая означает ошибку, и CONST2 больше всех не-ошибочных значений?

N>>Проверки полностью эквивалентны.

C>Разница в том, что в варианте с != если по какой-то причине кроме -1 функция может вернуть -2, то программа будет содержать ошибку.


Почему бы ей такое возвращать, если согласно контракту она может или >=0 (что-то полезное) или -1?

Если уж играться с тем, что зовётся defensive programming, то надо всегда проверять корректность результата вызываемой функции — как минимум, сразу писать if (rc < 0 && rc != -1) { взорваться нафиг; }. Ну и аналогично для прочих ситуаций.
Формально к этому можно даже найти обоснования. Например, у большинства линуксовых сисколлов такая обработка (псевдокод, оригинал на ассемблере):

int64_t rc = (int64_t) rax;
if (rc >= -4096 && rc <= -1) { errno = -rc; rc = -1; }
return rc;


В результате, если вызываемое вернуло (int64_t)(-8000) или что-то похожее, оно не будет опознано как код ошибки — и сохранено, например, как файловый дескриптор, если звалась open().

НО: чем данная ситуация отличается от 100500+ других нарушений — например, просто ошибочно другой дескриптор, неоткрытый файл, открытие не того пути, открытие с неправильными правами, и так далее? Всё это, если происходит, это "просто" ошибки реализации.

C> Ещё хуже то, что это неуправляемая память, и ошибка может проявиться как угодно: аварийное завершение, порча стека и т.д.


Ну вообще-то это не память, это другой ресурс (почти всегда). Например, файловый дескриптор. Хотя не так принципиально.

C> Если же мы проверяем через <, то мы поделили область определения функции на два диапазона. Математически эта функция становится составной функцией вида


C>{ f(x), x < X; g(x), X <= x; x э Z_uint32 }


Не знаю, какой у вас браузер, но ∈ это U+2208. Я стартую такой набор через Ctrl+Shift+U (свойство GTK). Под виндой есть свои методы.

C>и при этом остаётся total function (я не знаю, как по-русски), т.е. определена на всём промежутке значений входного аргумента.


В этих обозначениях, прямой результат функций типа open(), read() и так далее, является [0..INT_MAX] ∪ { -1 }.
Значения в диапазоне [INT_MIN..-2] невозможны.
И снова: если вы полагаетесь на корректность возврата такой функции, то проверки на x<0 и x==-1 эквивалентны. Если не полагаетесь, то надо проверять и случай заведомо некорректного возвращаемого значения.

C>C !=, конечно же, можно добиться аналогичного эффекта, но нужно тогда писать "x < 0", но так мало кто делает, это заметно даже по комментариям.


Я иногда так пишу. И всегда сомневаюсь, правильно ли это.
На x86 вариант "<0" компактнее на несколько байт. Обычно это не критично.
The God is real, unless declared integer.
Re: Коды ошибок и отрицательные числа
От: reversecode google
Дата: 31.01.22 11:12
Оценка:
компиляторы часто оптимизируют

if (r == -1)



преобразовывая в

if (r < 0)
Re[3]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.01.22 11:27
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Благодарю за хороший, полный ответ, но не согласен с


5M>>В 99.99% случаев когда ты размышляешь об операциях с числами, ты и читатели твоего кода подразумевают обычную, а не модульную арифметику


C>Для меня это не так. Я программист, я пишу программы, программы выполняются на ЭВМ, в ЭВМ целые числа это кольцо по модулю.


Anecdotal evidence обычно таки не работает.

5M>>B.Stroustrup “Subscripts and sizes should be signed”: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf


C>Ну эт классика — дед, который не пишет production ready код, учит нас жизни.


Думаю, что опыт, который он набрал в процессе разработки начальных версий C++, позволяет ему делать предложения для комитета, которые стоит как минимум послушать. И почему вы думаете, что сейчас он ничего не пишет в продуктин?

5M>>Длинное видео из 2013г где комитет C++ несколько раз признает ошибочность использования unsigned: https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything (12:10, 42:40, 1:02:50)


C>Не открывается =(


Оно есть на ютубе. Задумчиво смотрю сейчас в перерывах работы.

C>Я, кстати, больше пишу на Java, чем на Си и С++, и там, как бы, не из чего выбирать. Но если есть выбор, то почему бы им не воспользоваться? Если бы всё так было очевидно, то unsigned давно бы стал deprecated.


Ну вот то, что вы больше пишете на Java (и не только вы, а реально на Java в разы больше), показывает, что депрекация тут происходит несколько иными путями...
The God is real, unless declared integer.
Re[2]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 31.01.22 14:41
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Вы проверяете чужой код, видите следующий кусок:

C>
C>nread = my_read(...)
C>if (nread == -1)
C>    throw;
C>my_copy(src, dst, nread);
C>


C>Ваши действия?

Без знания контекста разработки ответить невозможно. Например, переписывание на:
nread = my_read(...)
if (nread <= -1)
    throw;
my_copy(src, dst, nread);

может требовать (согласно утверждённым методикам) написания дополнительного теста в котором my_read возвращает значение меньше -1. А если my_read никогда не возвращает такого, то тест никогда не будет признан пройденным => код не валиден, так как не протестирован.
И каждый день — без права на ошибку...
Re[3]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 31.01.22 14:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>может требовать (согласно утверждённым методикам) написания дополнительного теста в котором my_read возвращает значение меньше -1. А если my_read никогда не возвращает такого, то тест никогда не будет признан пройденным => код не валиден, так как не протестирован.


А что мешает использовать в тесте заглушку, которая вернёт нужное значение?
Re[4]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 31.01.22 15:07
Оценка:
Здравствуйте, cppguard, Вы писали:

BFE>>может требовать (согласно утверждённым методикам) написания дополнительного теста в котором my_read возвращает значение меньше -1. А если my_read никогда не возвращает такого, то тест никогда не будет признан пройденным => код не валиден, так как не протестирован.


C>А что мешает использовать в тесте заглушку, которая вернёт нужное значение?

Ничего: нужно написать ещё один специальный тест, описать что он тестирует, добавить в список исполняемых тестов... Затягивание сроков может быть выгодно, но приветствуется не всегда.
И каждый день — без права на ошибку...
Re[2]: Коды ошибок и отрицательные числа
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 31.01.22 15:38
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Всё очень просто 0-нет ошибки, не 0 — есть ошибка и всё.

Ну как так? А количество прочитанных байт? А результат нетривиальной успешной операции?
Sic luceat lux!
Re[4]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 31.01.22 17:59
Оценка:
Здравствуйте, cppguard, Вы писали:


Да, так и делается сейчас, но я этого не понимаю. Ведь куда как легче проверять код типа
unsgined nread = my_read(...)
if (nread >= 0)
    my_copy(src, dst, nread)
throw io_error(nread);
Re[3]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 31.01.22 18:06
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Ну эт классика — дед, который не пишет production ready код, учит нас жизни.


Я пишу продакшон. Беззнаковые индексы — это грабли.

C>Если бы всё так было очевидно, то unsigned давно бы стал deprecated.


Легаси...
Re[3]: Коды ошибок и отрицательные числа
От: kov_serg Россия  
Дата: 31.01.22 21:27
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, kov_serg, Вы писали:


_>>Всё очень просто 0-нет ошибки, не 0 — есть ошибка и всё.

K>Ну как так? А количество прочитанных байт? А результат нетривиальной успешной операции?

Вас что именно интересует?
int fn(fn_output_t *output,fn_input_t *input); // 0-нет ошибок, не 0 код ошибки

В частности
int my_read2(void *ctx,void *buffer,int size,int *readed) {
  int rd=my_read(ctx,buffer,size);
  if (readed) *readed=rd;
  return rd<0 ? rd : 0;
}

{
  int rc=0;
  ...
  int buf_size;
  if (my_read2(stream,buf,buf_lim,&buf_size)) { rc=my_error_read_problem; goto leave; }
  ...
leave:
  if (stream) my_close(stream);
  ...
  return rc;
}

  Скрытый текст
Или помещать результат вместе с кодами ошибок в структуру результата либо использовать std::tuple
struct my_read_result_t {
    my_read_result_t(int count) : value(count) {}
    int count() const { 
        if (invalid()) throw this;
        return value;
    }
    bool invalid() const { return value<0; }
private:
    int value;
};
my_read_result_t my_read(...) { ... }

std::tuple<bool,int> my_:read(...);


Или вам хочется странного можно хранить состояние в классе вместе с кодом ошибки.
struct Stream {
  ...
  int read(void* data,int size);
  bool error();
  int get_error_code();
};
...
  int rd=stream->read(count);
  if (stream->error()) {
    code=stream->get_error_code();
...


Можно просто завести функцию для проверки
int my_read(void *ctx,int count);
bool my_read_result_invalid(int res);

...
int rd=my_read(stream,count);
if (my_read_result_invalid(rd)) { panic(); }
...

Вариантов дофигища, но первый работает как в c так во всех c++ и его можно экспоритровать из динамической библиотеки не прибегая к костылям.
Re[6]: Коды ошибок и отрицательные числа
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 31.01.22 22:48
Оценка:
Здравствуйте, netch80, Вы писали:

M>>Поэтому надо просто писать

M>>
M>>for(auto i=0u; i!=v.size(); ++i)
M>>


N>А теперь повторите это для прохождения по элементам в порядке убывания индексов.


for (auto i = v.size(); i --> 0;)
Ce n'est que pour vous dire ce que je vous dis.
Re[3]: Коды ошибок и отрицательные числа
От: 5.März  
Дата: 01.02.22 01:21
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Ну эт классика — дед, который не пишет production ready код, учит нас жизни


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

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

C>Я, кстати, больше пишу на Java, чем на Си и С++, и там, как бы, не из чего выбирать.


Автор Java отказался включать в язык беззнаковые типы по той же самой причине:

> Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple.


Источник: http://www.gotw.ca/publications/c_family_interview.htm

В дотнете и тысяче других более-менее новых языков тоже все размеры и индексы знаковые, угадайте почему, вы бы лучше учились чем умничать.
Re[5]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.02.22 08:17
Оценка:
Здравствуйте, cppguard, Вы писали:

5M>>Для меня классикой уже стало наблюдать, как русские программисты выходят из тайги, отрицают все источники и авторитеты, и делают по-своему просто чтобы почувствовать себя чуть умнее, чем на самом деле. Откуда у нас столько одаренных людей берется, которые лучше знают что нужно дизайну языка, чем дизайнеры языка, ума не приложу


C>Страуструп создатель, а не дизайнер, дизайнер это коммитет.


Создатель, главный разработчик в течение многих лет (пока не пришлось действительно всё переложить на комитет), и один из дизайнеров (дизайнеры — было во множественном числе).
Разумеется, это само по себе не признак безусловной правоты, но, в отличие от любого из нас, кто видит от силы 10% языка, люди в комитете видят все варианты применения (вплоть до самых извращённых), получают массу сведений о проблемах, до которых крайне сложно самому додуматься, и так далее.

А ещё авторы языковых средств при реализации, просто от того, что они пишут компилятор, натыкаются на массу вопросов, как решить конкретный момент, и за счёт этого понимают язык сильно лучше того, кто на нём пишет.

C> Точно так же, как Java сейчас разрабатывает Оракл, а не Гослинг. Авторитеты в инженерном деле это идолопоклонничество. А людям из тайги своё мнение не положено, да?


Люди из тайги, повторю мысль, видят только тайгу. Человек из тайги может думать, что все едят оленей и кедровые орехи.

5M>>Он не учит вас жизни, а приводит аргументы, что знаковые были бы для языка лучше. Есть контраргументы — высказывайте... Или в универе больше не учат, что обсуждение личности человека не является опровержением его аргументов? Почему я в англоязычных дискуссиях подобного невежества не наблюдаю?


C>Потому что все нетоксичные, предельно вежливые и прочее, так заведено. Я видел обсуждения внутренних групп FAANG касательно всяких священных войн, и С++ в то числе, так там яд разве что через монитор не брызгал, но внешне, особенно для ex-USSR населения, всё выглядело чинно-благородно.


Психологический факт, что если (пусть даже насильно заставленные) люди высказываются в пределах корректности, это позволяет лучше обдумать позицию, и в итоге смягчить её, избавив от бессмысленного радикализма. Это не на 100% полезно, но конструктивная часть "нетоксичности" именно в этом.

C> А самое непрятное в таких обсуждениях то, что очень быстро от фактов и логических умозаключений переходят к "the results of most computations are signed" (слова Страуструпа), то есть полностью субъективному мнению,


Может, оно таки объективно? (см. выше)

C> а мнение это имеет очень большой вес. Вот и приходят в выводу "почему-бы не прислушаться к словам мэтра, он же велик". А код при этом сопровождают простые инженеры.


5M>>В дотнете и тысяче других более-менее новых языков тоже все размеры и индексы знаковые, угадайте почему, вы бы лучше учились чем умничать.


C>Я где-то писал, что индексы должны быть беззнаковые?


Тогда против чего вы возражаете данным сообщением? Страуструп высказывался в первую очередь про индексы и размеры.
The God is real, unless declared integer.
Re[12]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.02.22 08:25
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

N>>В любом случае, повторюсь, я поддерживаю, что в общем и целом со знаковыми удобнее хотя бы тем, что не надо следить за возможными проблемами перехода 0 -> 0-1. Вопрос был в конкретном примере.


АТ>Тема умения грамотно работать возле левого края интервалов вида [a, b) в условиях, когда выход за левый край интервала приводит к неожиданному, нежелательному или неопределенному поведению (ваши "проблемы перехода 0 -> 0-1"), является фундаментальным нативным свойством языков С и С++, да и вообще программирования в целом. Она распространяется не только на беззнаковые типы, но и на указательную арифметику, на итераторы, на потоки и на массу других концепций боле высокого уровня.


АТ>Поэтому попытки устранить эту "проблему" в области индексирования массивов — это локальное решение, которое ничего не поменяет в общем. Следить за "возможными проблемами перехода 0 -> 0-1" в более обобщенно понимании вам все равно придется ничуть не меньше чем ранее. Ценность "неудобной" беззнаковой арифметики в индексации заключается в том числе в том, что она с ранних пелёнок оповещает подрастающее поколение о существовании этой темы, с которой им в дальнейшем придется сталкиваться постоянно (независимо от того, какие типы они будут фактически использовать для индексации). Переход на знаковые типы лишь замедлит процесс формирования ценных идиом.


Интересные доводы, я сохранил. Но по отношению к ним есть принципиальные проблемы: в первую очередь этот как раз состоявшийся по факту "алиасинг" modulo-типа не вполне корректным словом unsigned (о чём тут вспоминал коллега σ). "Формирование ценных идиом" должно начинаться с этого (и объяснения, в чём авторы стандарта тут подложили каку). А тут уже вопрос обучения: я пока что ни в одном популярном учебнике по C или C++ не видел, чтобы в это явно ткнули носом (а для большинства таки надо ткнуть, я не был исключением).

Ну и в итоге это имеет ценность только до тех пор, пока сохраняется совместимость с данной... мнэээ... особенностью эхотага. Учить тому, что не надо идти, например, от begin() на шаг назад, это универсально.
The God is real, unless declared integer.
Re[4]: Коды ошибок и отрицательные числа
От: sergii.p  
Дата: 01.02.22 09:55
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, netch80, Вы писали:


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

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

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


уж что-что, но это не обычный заголовок. В данном случае .. в терминах математики означает [0; v.len()-1). Последний элемент не включается. То есть вы ещё один элемент откусили от вектора.

так ошибки нет вовсе:
for i in 0 .. v.len()


конечно можно постараться и таки выстрелить в ногу:
for i in 0 ..= v.len() - 1


А такой код уже работает:
for i in 0 ..= v.len() as i8 - 1


Вообще циклы добавили в раст для выявления профнепригодности. Итераторы же есть.
Re[6]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 01.02.22 10:06
Оценка:
Здравствуйте, netch80, Вы писали:

N>Разумеется, это само по себе не признак безусловной правоты, но, в отличие от любого из нас, кто видит от силы 10% языка, люди в комитете видят все варианты применения (вплоть до самых извращённых), получают массу сведений о проблемах, до которых крайне сложно самому додуматься, и так далее.


Есть разница в том, чтобы видеть различные примеры использования языка и понимать на практике сильные и слабые стороны.

N>Люди из тайги, повторю мысль, видят только тайгу. Человек из тайги может думать, что все едят оленей и кедровые орехи.


А люди из Сан-Франциско — только бомжей и ссанину, и что? Я тут вашу мысль не понял. Мысль предыдущего оратора понятна — "куда в со своим свиным рылом в калашный ряд, ещё иметь своё мнение посмели". И в предложении "дед учит жизни" нет ничего токсичного. Я даже на личности не переходил. Страуструп действительно дед, а тон его статьи вкупе с тем, что никаких примеров из реальной жизни (рабочий код, открытые проекты) он не привёл, позволяет использоваться оборот "учить жизни", который оскорбительным в целом и не является.

N>Может, оно таки объективно? (см. выше)


Как могут быть объективными слова "the most of computations" без приведения статистики? Или Страуструп у нас уже Чак Норрис и видел весь код на свете, два раза? Аналогично можно сказать "the most of integer additions overflow, so let's make it long long by default".

N>Тогда против чего вы возражаете данным сообщением? Страуструп высказывался в первую очередь про индексы и размеры.


Против его аргументов. И не возражаю, а просто высказал своё мнение насчёт ценности статьи. Но знал бы, что комментарий породит столько флуда, не стал бы писать, чтобы не увеличивать мировую энтропию =) Предлагаю на этом закончить обсуждение в этой ветке. Я получил комментарии, было очень интересно узнать новое, есть над чем подумать.
Re[4]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 01.02.22 10:18
Оценка:
Здравствуйте, T4r4sB, Вы писали:

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

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

Я, не зная языка rust, а просто исходя из записи ожидаю, что при пустом v индекс i будет принимать значения [0, -1). Если предположить, что для диапазона [0, -2) i будет принимать значения {0, -1}, то для диапазона [0, -1) индекс i будет принимать значение {0}.

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

TB>Так что нет, индексы и размеры должны быть знаковыми и только знаковыми.
Мне не понятно, причём тут знаковость. В rust нельзя писать так: for i in 0 .. -8 ?
И каждый день — без права на ошибку...
Re[5]: Коды ошибок и отрицательные числа
От: sergii.p  
Дата: 01.02.22 11:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Мне не понятно, причём тут знаковость. В rust нельзя писать так: for i in 0 .. -8 ?


можно, но в примере выше v.len() — 1 преобразуется не к -1, а к maxint (это в релизе, в дебаге паника будет раньше)
Посмотрим на такой (безумный) код:
let v: Vec<u8> = Vec::new();
let sum: usize = (0..v.len() - 1).sum();


если бы len было ssize получили бы
(0..-1).sum() // 0


а так получим суммирование всех элементов до maxint с переполнением и прочими прелестями.
Re[5]: Коды ошибок и отрицательные числа
От: kov_serg Россия  
Дата: 01.02.22 12:00
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Да, так и делается сейчас, но я этого не понимаю. Ведь куда как легче проверять код типа

TB>
TB>unsgined nread = my_read(...)
TB>if (nread >= 0)
TB>    my_copy(src, dst, nread)
TB>throw io_error(nread);
TB>

Тролите
Re[7]: Коды ошибок и отрицательные числа
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.02.22 12:36
Оценка:
Здравствуйте, cppguard, Вы писали:
C>Как могут быть объективными слова "the most of computations" без приведения статистики? Или Страуструп у нас уже Чак Норрис и видел весь код на свете, два раза? Аналогично можно сказать "the most of integer additions overflow, so let's make it long long by default".
Страуструп имел в виду, что первое же вычитание делает вычисление знаковым. Ну, потому, что очень мало кто ожидает при вычислении (5 — 8) получить 18446744073709551613, а не -3.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 01.02.22 14:09
Оценка:
Здравствуйте, netch80, Вы писали:

M>>Поэтому надо просто писать

M>>
M>>for(auto i=0u; i!=v.size(); ++i)
M>>


N>А теперь повторите это для прохождения по элементам в порядке убывания индексов.


for(auto i = v.size()-1; i != -1; --i)
...


Обоснование:

7.4 Usual arithmetic conversions
Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield
result types in a similar way.
...
— Otherwise, the integral promotions (7.3.6) shall be performed on both operands.56 Then the following rules shall be applied to the promoted operands:
...
(1.5.3) — Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the
rank of the type of the other operand, the operand with signed integer type shall be converted to
the type of the operand with unsigned integer type.

Так что -1 конвертируется в unsigned integer type.

Согласно 6.8.1 Fundamental types

An unsigned integer type has the same width N as the corresponding signed integer type. The range of representable values for the unsigned type is 0 to 2N − 1 (inclusive); arithmetic for the unsigned type is performed modulo 2N.


Согласно правилам модульной арифметики

Given an integer n > 1, called a modulus, two integers a and b are said to be congruent modulo n, if n is a divisor of their difference (i.e., if there is an integer k such that a − b = kn).

Для нас n = 2N. Математически число -1 сравнимо по модулю с числом (2N − 1), так как 2N − 1 — (-1) = 2N, а 2N делится на 2N без остатка. Следовательно -1 будет конвертировано в 2N−1 и цикл отработает как надо.
И каждый день — без права на ошибку...
Re[5]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 01.02.22 17:34
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Я, не зная языка rust, а просто исходя из записи ожидаю, что при пустом v индекс i будет принимать значения [0, -1). Если предположить, что для диапазона [0, -2) i будет принимать значения {0, -1}, то для диапазона [0, -1) индекс i будет принимать значение {0}.


Ээээ, вообще-то [0, -1), и [0, -2) тоже — это пустой диапазон

BFE>Мне не понятно, причём тут знаковость. В rust нельзя писать так: for i in 0 .. -8 ?


Можно, только v.len() имеет беззнаковый тип. Можно вручную скастить, только какого хрена я должен засирать код этим бойлерплейтом из-за чьей-то придури?
Re[6]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 01.02.22 17:35
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Тролите


Я пытаюсь показать, что между частями его сообщения нет никакой логической связи. Делаю я это, меняя посылку на противоположную, демонстрируя, что при этом ничего по сути не меняется.
Re[8]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 01.02.22 17:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, cppguard, Вы писали:

C>>Как могут быть объективными слова "the most of computations" без приведения статистики? Или Страуструп у нас уже Чак Норрис и видел весь код на свете, два раза? Аналогично можно сказать "the most of integer additions overflow, so let's make it long long by default".
S>Страуструп имел в виду, что первое же вычитание делает вычисление знаковым. Ну, потому, что очень мало кто ожидает при вычислении (5 — 8) получить 18446744073709551613, а не -3.

Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

Страуструп говорит совсем другое. Страуструп говорит, что в ситуации, когда "в аудитории было 5 студентов, затем пришли еще 3, а затем ушли 8" безалаберный Джонни может начать с вычитания 5 — 8 и получения пугающего Джонни результата (даже если в итоге он приведет к правильному ответу). И чтобы программирование стало менее пугающим для таких безалаберных Джонни, лучше сразу работать в знаковой арифметике.
Best regards,
Андрей Тарасевич
Re[7]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 01.02.22 17:48
Оценка:
Здравствуйте, B0FEE664, Вы писали:

N>>А теперь повторите это для прохождения по элементам в порядке убывания индексов.


BFE>
BFE>for(auto i = v.size()-1; i != -1; --i)
BFE>...
BFE>


Это — правильно, но содержит другой подводный камень. Если вдруг окажется, что `size()` возвращает "маленький" беззнаковый тип, т.е. тип подпадающий под integral promotions, то цикл снова получится бесконечным.

Идиоматический код для обратной итерации до нуля прекрасно известен

for (auto i = v.size(); i > 0; )
{
  --i;
  
  //...
}


или, если вы предпочитаете

for (auto i = v.size(); i-- > 0; )
{
  //...
}


Все.

Эта идиома, еще раз, пригодится не только при работе с беззнаковой арифметикой, но и, как я уже говорил выше, для обратной итерации по любым интервалам, выход за левую границу которых недопустим: интервалы итераторов, интервалы указателей, и т.п.
Best regards,
Андрей Тарасевич
Отредактировано 01.02.2022 17:59 Андрей Тарасевич . Предыдущая версия .
Re[13]: Коды ошибок и отрицательные числа
От: Андрей Тарасевич Беларусь  
Дата: 01.02.22 17:55
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>Она распространяется не только на беззнаковые типы, но и на указательную арифметику, на итераторы, на потоки и на массу других концепций боле высокого уровня.


TB>И как же сложить два итератора? Или два потока?

TB>Индекс можно являться участником арифметических выражений (и является), а итератор, ну разве что в a-b, и то только для векторов.

Это не имеет никакого отношения к рассматриваемой теме.

К рассматриваемой теме имеет отношение то, что для ряда дискретных "итераторных" сущностей диапазоны вида [a, b) невозможно тривиальным образом превратить в обратные диапазоны [b-1, a-1) по той причине, что выражение `a-1` либо вообще не определено, либо дает "неправильный" результат. Это относится и к беззнаковой индексации/позиционированию, и к итераторам/указателям и еще очень много к чему. В этом и состоит суть рассматриваемой проблемы.
Best regards,
Андрей Тарасевич
Отредактировано 01.02.2022 18:00 Андрей Тарасевич . Предыдущая версия .
Re[9]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.02.22 18:27
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

S>>Страуструп имел в виду, что первое же вычитание делает вычисление знаковым. Ну, потому, что очень мало кто ожидает при вычислении (5 — 8) получить 18446744073709551613, а не -3.


АТ>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.


Что за жёлтая муть?
В мире существует множество разных понятий, которые можно свести к числам, и, например, векторов (включая противоположно направленные) в нём не меньше, чем чисел.
И даже количество материи может быть отрицательным (временно, на квантовом уровне).

АТ>Страуструп говорит совсем другое. Страуструп говорит, что в ситуации, когда "в аудитории было 5 студентов, затем пришли еще 3, а затем ушли 8" безалаберный Джонни может начать с вычитания 5 — 8 и получения пугающего Джонни результата (даже если в итоге он приведет к правильному ответу). И чтобы программирование стало менее пугающим для таких безалаберных Джонни, лучше сразу работать в знаковой арифметике.


Проблема, да, в самой операции вычитания и определения корректности промежуточных значений. Не бывает отрицательного количества студентов, редко бывает в чистом виде отрицательных денег (случай кредита под 0% это всё равно кредит), и так далее — и что, от этого не пользоваться этими числами, когда это не нарушает корректность модели?

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

Но в таких операциях проще понять (обычно), если вылезешь в минус.
А вот отсутствие for с постпроверкой, например, приводит к грустным костылям.
The God is real, unless declared integer.
Re[14]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 01.02.22 18:48
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>К рассматриваемой теме имеет отношение то, что для ряда дискретных "итераторных" сущностей диапазоны вида [a, b) невозможно тривиальным образом превратить в обратные диапазоны [b-1, a-1) по той причине, что выражение `a-1` либо вообще не определено, либо дает "неправильный" результат. Это относится и к беззнаковой индексации/позиционированию, и к итераторам/указателям и еще очень много к чему. В этом и состоит суть рассматриваемой проблемы.


Значит для итераторов арифметика не работает, только и всего.
Это не повод портить арифметику индексов
Re[7]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.02.22 20:29
Оценка:
Здравствуйте, cppguard, Вы писали:

N>>Разумеется, это само по себе не признак безусловной правоты, но, в отличие от любого из нас, кто видит от силы 10% языка, люди в комитете видят все варианты применения (вплоть до самых извращённых), получают массу сведений о проблемах, до которых крайне сложно самому додуматься, и так далее.


C>Есть разница в том, чтобы видеть различные примеры использования языка и понимать на практике сильные и слабые стороны.


И вы всерьёз считаете, что человек, который пусть сам пишет, но один частный вариант, будет лучше понимать тонкости, чем тот, кто пусть пишет примерчики и мелкие тесты, но зато видит от других огромное количество вариантов, о которых бы никогда не додумался?

N>>Люди из тайги, повторю мысль, видят только тайгу. Человек из тайги может думать, что все едят оленей и кедровые орехи.

C>А люди из Сан-Франциско — только бомжей и ссанину, и что? Я тут вашу мысль не понял.

См. выше.

C> Страуструп действительно дед, а тон его статьи вкупе с тем, что никаких примеров из реальной жизни (рабочий код, открытые проекты) он не привёл,


Примеры, я уверен, специально подобраны так, чтобы отображать конкретную идею на минимальном количестве символов. Для этого им не нужно быть выдиркой реального кода, скорее наоборот.

C> позволяет использоваться оборот "учить жизни", который оскорбительным в целом и не является.


Но всё отношение к нему — было однозначно уничижительным.

N>>Может, оно таки объективно? (см. выше)

C>Как могут быть объективными слова "the most of computations" без приведения статистики? Или Страуструп у нас уже Чак Норрис и видел весь код на свете, два раза? Аналогично можно сказать "the most of integer additions overflow, so let's make it long long by default".

long long тоже переполнится
Статистика тут, безусловно, будет врать без уточнения разделения по крупным сродственным группам (типа, в среднем человек имеет одну грудь), но про источники можно было попытаться спросить напрямую. Вообще, ACM и IEEE (как минимум) периодически собирают такие данные.

N>>Тогда против чего вы возражаете данным сообщением? Страуструп высказывался в первую очередь про индексы и размеры.


C>Против его аргументов. И не возражаю, а просто высказал своё мнение насчёт ценности статьи. Но знал бы, что комментарий породит столько флуда, не стал бы писать, чтобы не увеличивать мировую энтропию =) Предлагаю на этом закончить обсуждение в этой ветке. Я получил комментарии, было очень интересно узнать новое, есть над чем подумать.


Я тоже. И продолжу поддерживать как знаковость по умолчанию, так и мастдайность эхотага с заменой на что-то приличное как можно быстрее
The God is real, unless declared integer.
Re[7]: Коды ошибок и отрицательные числа
От: kov_serg Россия  
Дата: 01.02.22 20:43
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, kov_serg, Вы писали:


_>>Тролите


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


просто unsigned почти всегда >=0, (кроме случаев с "умным" компилятором и неопределенной переменной)
Re[8]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 01.02.22 20:57
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>просто unsigned почти всегда >=0, (кроме случаев с "умным" компилятором и неопределенной переменной)


Дык он хочет проверять unsigned<BIG_VALUE, и говорит, что это проще, чем проверить signed>=0
Re[8]: Коды ошибок и отрицательные числа
От: cppguard  
Дата: 02.02.22 00:28
Оценка:
Здравствуйте, netch80, Вы писали:

N>И вы всерьёз считаете, что человек, который пусть сам пишет, но один частный вариант, будет лучше понимать тонкости, чем тот, кто пусть пишет примерчики и мелкие тесты, но зато видит от других огромное количество вариантов, о которых бы никогда не додумался?


Я, честно, не вижу смысла в этом споре. Просто для справки: коммитет (со Страуструпом среди прочих) подарили нам мёртворождённый auto_ptr и string, который сначала copy-on-write, а потом never copy-on-write. Это, конечно же, они сделали на основе своего глупокого и многолетнего опыта разработки.

N>Но всё отношение к нему — было однозначно уничижительным.


Отнюдь. Максимум — шутливое.
Re[9]: Коды ошибок и отрицательные числа
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.22 03:42
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

И каков же в нашем мире результат вычитания 8 из 5?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.02.22 07:48
Оценка:
Здравствуйте, cppguard, Вы писали:

N>>И вы всерьёз считаете, что человек, который пусть сам пишет, но один частный вариант, будет лучше понимать тонкости, чем тот, кто пусть пишет примерчики и мелкие тесты, но зато видит от других огромное количество вариантов, о которых бы никогда не додумался?


C>Я, честно, не вижу смысла в этом споре. Просто для справки: коммитет (со Страуструпом среди прочих) подарили нам мёртворождённый auto_ptr и string, который сначала copy-on-write, а потом never copy-on-write. Это, конечно же, они сделали на основе своего глупокого и многолетнего опыта разработки.


"глупокий" — хорошее слово. Случайно или намеренно?

В случае string, я подозреваю, это ориентация на типовые свойства процессоров. За ~20 лет, например, важность кэширования и проблем с ним возросла не просто — с минимума до всепоглощающего уровня.
Похожая реформа прошла и в Java — JVMы перешли на не-COW строки в районе Java 8.
С auto_ptr — я пропустил период его значимости (я плотно вернулся к C++ в районе 2014) и не знаю, какие там фундаментальные проблемы. cppreference.com описывает по сути только одно: у него копирование работает как перемещение. С учётом того, что с 1988 по 2011 не могли стандартизовать семантику перемещения, проблема сидела где-то глубже — в районе принципиальной способности комитета принять решения — но что мешало тогда, честно, облом вкапываться, это совсем другая проблема.

Тем не менее, отдельные ляпы не дают причин сомневаться в неработоспособности механизма узнавания фундаментальных проблем в целом.

N>>Но всё отношение к нему — было однозначно уничижительным.

C>Отнюдь. Максимум — шутливое.

Ну ok...
The God is real, unless declared integer.
Re[8]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 02.02.22 09:09
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

N>>>А теперь повторите это для прохождения по элементам в порядке убывания индексов.

BFE>>
BFE>>for(auto i = v.size()-1; i != -1; --i)
BFE>>...
BFE>>


АТ>Это — правильно, но содержит другой подводный камень. Если вдруг окажется, что `size()` возвращает "маленький" беззнаковый тип, т.е. тип подпадающий под integral promotions, то цикл снова получится бесконечным.

Если писать с нулевой терпимостью к предупреждениям, то тогда и в этом случае проблем не будет:
for(auto i = v.size()-1; i != static_cast<decltype(i)>(-1); --i)


АТ>Идиоматический код для обратной итерации до нуля прекрасно известен

Да, он состоит в том, чтобы использовать итераторы в связке с std:/std::ranges::for_each
Индексы редко нужны.
И каждый день — без права на ошибку...
Re[10]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 02.02.22 09:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

АТ>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>И каков же в нашем мире результат вычитания 8 из 5?
В реальном мире = 0. С оговоркой, что 0 — это пусто.
В мире идей = -3.
Выберите свой мир.
И каждый день — без права на ошибку...
Re[12]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 02.02.22 10:00
Оценка:
Здравствуйте, netch80, Вы писали:

АТ>>>>Нет. Кардинальные (количественные) вычисления всегда беззнаковы, сколько бы вы ни занимались вычитаниями. Наш мир принципиально беззнаков по отношению к количественным величинам. И становиться "знаковым" из-за вычитания ему нет никакой необходимости.

S>>>И каков же в нашем мире результат вычитания 8 из 5?
BFE>>В реальном мире = 0. С оговоркой, что 0 — это пусто.
N>Точно не ноль. Скорее — исключение по невозможности совершить операцию.
Исключение в реальном мире? Это как? Допустим вы полезли в холодильник с целью достать оттуда 8 куриных яиц, а там только 5. И тут случилось "исключение по невозможности совершить операцию". Что это может быть?

BFE>>В мире идей = -3.

BFE>>Выберите свой мир.
N>Ваша вселенная удивительна, но людям там слегка не место.
В современном мире реалисты встречаются редко: одни в бога верят, другие — в отрицательные числа...
И каждый день — без права на ошибку...
Re[11]: Коды ошибок и отрицательные числа
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 02.02.22 10:20
Оценка:
Здравствуйте, B0FEE664, Вы писали:

S>>И каков же в нашем мире результат вычитания 8 из 5?

BFE>В реальном мире = 0. С оговоркой, что 0 — это пусто.
BFE>В мире идей = -3.

В реальном мире нет ни 8, ни 5 — это всё абстракции, придуманные человеком для универсального описания реальности. Вот ты смог этими числами описать, например, число яиц в холодильнике. Также можно описать число яблок или вершин в многоугольнике. В реальном мире нет математики в принципе.
Re[12]: Коды ошибок и отрицательные числа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.02.22 10:32
Оценка:
Здравствуйте, Nuzhny, Вы писали:

S>>>И каков же в нашем мире результат вычитания 8 из 5?

BFE>>В реальном мире = 0. С оговоркой, что 0 — это пусто.
BFE>>В мире идей = -3.
N>В реальном мире нет ни 8, ни 5 — это всё абстракции, придуманные человеком для универсального описания реальности.

Ну это тоже перегиб. Понятно, что все яйца разные, но с какой-то погрешностью можно обобщить их до одинаковости, особенно если одного типа из одной партии. Точно так же и в принципах типа "взрослому амурскому тигру зимой надо 20 кг мяса в сутки" (неважно, точная цифра или нет, но можно считать животных в этом смысле примерно эквивалентными).
Масса материи универсальна с хорошей точностью (релятивистские эффекты нам обычно неактуальны, и ядерный реактор не обсчитываем). И так далее.

N> Вот ты смог этими числами описать, например, число яиц в холодильнике. Также можно описать число яблок или вершин в многоугольнике. В реальном мире нет математики в принципе.


Есть. Но реализуется обычно иначе и сложнее. E=m*c**2, законы Ньютона, уравнения Максвелла и 100500 прочих аналогичных законов.

И в них и отрицательные числа сплошь и рядом, и сложение векторов разных знаков...

А вот целые и особенно рациональные числа, если это не коэффициенты или степени — это таки редкость (ну, в квантовом мире таки чаще, там ½ на каждом углу). Основная масса — вещественные, естественно бесконечной (насколько известно) точности.
The God is real, unless declared integer.
Re[13]: Коды ошибок и отрицательные числа
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 02.02.22 10:48
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну это тоже перегиб. Понятно, что все яйца разные, но с какой-то погрешностью можно обобщить их до одинаковости, особенно если одного типа из одной партии. Точно так же и в принципах типа "взрослому амурскому тигру зимой надо 20 кг мяса в сутки" (неважно, точная цифра или нет, но можно считать животных в этом смысле примерно эквивалентными).


Я не считаю это перегибом. Если кто-то не видит отрицательных чисел в природе, то почему я должен видеть целые или дроби? Если говорить ро ноль, то это тоже очень не интуитивная штука, его люди изобрели достаточно поздно.

N>Есть. Но реализуется обычно иначе и сложнее. E=m*c**2, законы Ньютона, уравнения Максвелла и 100500 прочих аналогичных законов.


Я же не утверждаю, что самих явлений не существует. Явления существуют и мы описываем наблюдения над ними с помощью абстракций — математики. Сначала придумали натуральные числа, расширили их нулём, додумали дроби, добавили отрицательные, смогли записывать формулы и уравнения. Не вижу разницы между всеми этими абстракциями, кроме как что некоторые более, а другие менее интуитивны. Даже больше: одни и те же явления можно описывать разными абстракциями, например можно сравнить углы Эйлера и кватернионы. Первые интуитивны, вторые не очень, но какая разница?

N>И в них и отрицательные числа сплошь и рядом, и сложение векторов разных знаков...


Абсолютно согласен.

Самое интересное будет, если обнаружится в принципе совсем другая математика, сособная также хорошо описывать природу, но остроенная на абсолютно других ринципах и без всяих натуральных числах и аксиом Пеано.
Re[12]: Коды ошибок и отрицательные числа
От: B0FEE664  
Дата: 02.02.22 14:08
Оценка:
Здравствуйте, Nuzhny, Вы писали:

S>>>И каков же в нашем мире результат вычитания 8 из 5?

BFE>>В реальном мире = 0. С оговоркой, что 0 — это пусто.
BFE>>В мире идей = -3.

N>В реальном мире нет ни 8, ни 5 — это всё абстракции, придуманные человеком для универсального описания реальности. Вот ты смог этими числами описать, например, число яиц в холодильнике. Также можно описать число яблок или вершин в многоугольнике. В реальном мире нет математики в принципе.


Продолжая эту вашу мысль легко прийти к тому, что человеческого языка не существует, т.к. это придуманное человеком символическое универсальное описание реальности. Однако язык, как явление, несомненно существует и реален. Другое дело, что язык не ограничен описание только реальных вещей и явлений, но так же позволяет описать то, чего не существует. Так же и с математическими абстракциями — с их помощью можно выразить то, чего не существует, причём не только в реальном мире, но и в мире идей. Например, считается, что в математике не существует противоречий и на основе этого строятся все доказательства «от противного».
И каждый день — без права на ошибку...
Re[13]: Коды ошибок и отрицательные числа
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 02.02.22 14:30
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Продолжая эту вашу мысль легко прийти к тому, что человеческого языка не существует, т.к. это придуманное человеком символическое универсальное описание реальности.


Не вижу, как оно следует.

BFE>Однако язык, как явление, несомненно существует и реален. Другое дело, что язык не ограничен описание только реальных вещей и явлений, но так же позволяет описать то, чего не существует. Так же и с математическими абстракциями — с их помощью можно выразить то, чего не существует, причём не только в реальном мире, но и в мире идей. Например, считается, что в математике не существует противоречий и на основе этого строятся все доказательства «от противного».


Никто так не считает уже последние 100 лет точно, с тех пор как под математику начали подводить аксиоматическое основание.
Re[13]: Коды ошибок и отрицательные числа
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.22 14:39
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А то! Смотрите, что пишет T4r4sB
Автор: T4r4sB
Дата: 01.02.22
:

BFE>

BFE>Ээээ, вообще-то [0, -1), и [0, -2) тоже — это пустой диапазон

Всё верно пишет. Множество решений системы уравнений (X > 10; X < 2) тоже является пустым.
BFE>Отрицание существования отрицательных чисел интуитивно согласуется с этим утверждением.
Интуиция — плохой инструмент для научных и инженерных задач.
BFE>Ну, а если вы думаете, что отрицательные числа существуют, то покажите мне минус пять яблок. Именно яблок, а не их огрызков.
Эмм. Я не говорил, что существуют отрицательные яблоки. Но каким образом вы из этого выводите несуществование отрицательных чисел, мне непонятно.
Тем же способом мы легко можем "опровергнуть" существование рациональных чисел: покажите мне половинку электрона. Или одну восьмую.

BFE>На дворе коронавирус, а вы себя за лицо хватаете...

Я привит.

BFE>Числа — это всё условности:

BFE>
BFE>for(unsigned i = 2; i != -4; --i)
BFE>  std::cout << i << std::endl;
BFE>

BFE>2
BFE>2
BFE>1
BFE>0
BFE>4294967295
BFE>4294967294
BFE>4294967293
BFE>

Совершенно верно. Я правильно понимаю, что вы считаете, что при извлечении из холодильника с пятью яйцами семи яиц в нём останется 4294967294 яйца?
Или вам этот результат кажется интуитивно более корректным, чем -2?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Коды ошибок и отрицательные числа
От: sergii.p  
Дата: 02.02.22 15:41
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Вот только индексация универсальнее итератора, и оптимизируется лучше.


оно конечно так. Если бы ещё человеки умели делать индексацию без ошибок. Оставьте компьютеру компьютерово. Даже в "обычных заголовках" "пенсионеры" делают ошибки. Что уж говорить про менее тривиальные примеры.
Re[11]: Коды ошибок и отрицательные числа
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.22 17:44
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>В мире количественных вычислений не бывает не только "результата вычитания 8 из 5", но не бывает даже и необходимости вычитать 8 из 5. Возникновение такой необходимости в каких-либо выкладках — это звоночек, говорящий, что где-то раньше вы совершили ошибку и забрели не в ту степь.

Если речь о кардинальных числах, то в их алгебре нет не просто вычитания 8 из 5, там вообще вычитания нет.
О чём я и говорил — введение операции вычитания разрушает замкнутость алгебры, и приходится выйти за пределы неотрицательных чисел.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Коды ошибок и отрицательные числа
От: 5.März  
Дата: 02.02.22 22:25
Оценка:
Здравствуйте, T4r4sB, Вы писали:

5M>>В дотнете и тысяче других более-менее новых языков тоже все размеры и индексы знаковые

TB>Но комитет Раста решил всё сделать через жопу

Согласен, и самое забавное у них что макс. размер вектора все равно isize::max а не usize::max, все, чего они добились беззнаковостью это жалобы на слишком много кастов при работе с индексами.

Ну они хотя бы соломку попытались подстелить: в Debug режиме и знаковые и беззнаковые обрывают программу при переполнении т.е. арифметика подразумевается нормальная независимо от знаковости, плюс неявные преобразования между знаковыми и беззнаковыми без каста запрещены.
Re[6]: Коды ошибок и отрицательные числа
От: T4r4sB Россия  
Дата: 03.02.22 20:47
Оценка:
Здравствуйте, 5.März, Вы писали:

5M>Согласен, и самое забавное у них что макс. размер вектора все равно isize::max а не usize::max, все, чего они добились беззнаковостью это жалобы на слишком много кастов при работе с индексами.


А они на эти жалобы как-то реагируют? Ну в лучшем случае хотелось бы "мы признаём ошибку, но менять легаси сложно", а не "вы ничиво напинимаити1111 кхампайл-тхаймовый инвариант ниатрицатильнасти111".
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.