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

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

Изменено 30.01.2022 7:14 Андрей Тарасевич

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

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


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

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

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