Здравствуйте, netch80, Вы писали:
N>"unsigned адресация" в пространстве индексов массивов C, vector и array C++, прочих контейнеров C++ просто не существует
Это с точки зрения прикладника может быть. А как только ныряешь ближе к железу то начинаются нюансы.
В kernel пространстве адресов unsigned ещё как существует.
В storage то же самое.
И когда сраные теоретики влазят туда с со своими сраными signed идеями — последствия получаются ну очень матерные.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Alekzander, Вы писали:
A>Это ж как надо себя не уважать, чтобы что-то отвечать тому, кого считаешь тухлой селёдкой.
Негоже позволять "тухлой селёдкой" нести чушь
A>Тем более, после того, как "селёдка" послала тебя нахер.
Обожежтымой, я потеряю покой и сон!
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Pauel, Вы писали:
P>Да уж прям таки — вы как то узнали, что надо исправить код в том самом месте
Стало интересно как у меня сделано что проблем нет.
Пошёл в свой код, посмотрел как там написано: там было +=
Написал в твоём примере так же — заработало.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
N>>"unsigned адресация" в пространстве индексов массивов C, vector и array C++, прочих контейнеров C++ просто не существует CC>Это с точки зрения прикладника может быть. А как только ныряешь ближе к железу то начинаются нюансы. CC>В kernel пространстве адресов unsigned ещё как существует.
Ты, кажется, и не пытался понять, что я написал.
CC>В storage то же самое. CC>И когда сраные теоретики влазят туда с со своими сраными signed идеями — последствия получаются ну очень матерные.
Да-да, я помню твой рассказ про индексацию LBA где-то под NVMe.
Но рекомендую не терять из виду, что это не unsigned. Это modulo, замаскированный из-за кривости C под простой unsigned.
Здравствуйте, netch80, Вы писали:
N>Ты, кажется, и не пытался понять, что я написал.
Тебя порой сложновато понять.
Теория меня интересует исключительно с точки зрения применения на практике. Всякие "внутренние красоты" и "концептуальные значения" давно уже не интересуют.
N>Да-да, я помню твой рассказ про индексацию LBA где-то под NVMe. N>это не unsigned. Это modulo, замаскированный из-за кривости C под простой unsigned.
В каком месте в концепции LBA ты увидел modulo?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, CreatorCray, Вы писали: CC>>Написал в твоём примере так же — заработало. S>Повторяю: не заработало. S>https://godbolt.org/z/8jz98GEaK
Ещё раз повторяю, я не особо и старался.
Но если ты настаиваешь: https://godbolt.org/
На каждую хитрую жопу...
Работает в обоих случаях (и с volatile переменной и с константой): https://godbolt.org/
PS. Интересно, а проверку на NaN через сравнение с самими собой эти оптимизаторы когда сломают?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали: CC>На каждую хитрую жопу... CC>Работает в обоих случаях (и с volatile переменной и с константой): https://godbolt.org/
У вас ссылка битая. Там надо нажимать на кнопку share в правом верхнем углу.
(Мне просто интересно, какой вариант будет считаться верным от мастера C++. Сам-то я вообще не программист, поэтому мои идеи наверняка не пройдут code review)
((И ещё, конечно же, интересно, какой код у вас бегает в production. Пока что у меня два варианта:
— у вас там нет UB, потому что вы используете чутка другую арифметику
— у вас там UB, и в коде есть мина замедленного действия, о которой вы не подумали))
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
CC>>Работает в обоих случаях (и с volatile переменной и с константой): https://godbolt.org/ S>У вас ссылка битая. Там надо нажимать на кнопку share в правом верхнем углу.
Грёбаный сайт!
S>(Мне просто интересно, какой вариант будет считаться верным от мастера C++.
А кого будем считать мастером? Тут мнения очень сильно расходятся.
S> Сам-то я вообще не программист
Разве?
S> И ещё, конечно же, интересно, какой код у вас бегает в production.
Без template is_max, на порядки более прямолинейный и использующий только то, что нужно именно тут и сейчас.
Я код пишу не для вакуума, а под конкретные требования, включающие и компилятор.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Грёбаный сайт!
Боюсь, проблема не только в сайте
Вы избавились от UB, и теперь ваш код работает неправильно всегда, даже в -O0: https://godbolt.org/z/ToKv8Kx3d
icc: remark #10441: The Intel(R) C++ Compiler Classic (ICC) is deprecated and will be removed from product release in the second half of 2023. The Intel(R) oneAPI DPC++/C++ Compiler (ICX) is the recommended compiler moving forward. Please transition to use this compiler. Use '-diag-disable=10441' to disable this message.
ASM generation compiler returned: 0
icc: remark #10441: The Intel(R) C++ Compiler Classic (ICC) is deprecated and will be removed from product release in the second half of 2023. The Intel(R) oneAPI DPC++/C++ Compiler (ICX) is the recommended compiler moving forward. Please transition to use this compiler. Use '-diag-disable=10441' to disable this message.
Execution build compiler returned: 0
Program returned: 0
oops
CC>А кого будем считать мастером? Тут мнения очень сильно расходятся.
Я верю людям на слово. Поэтому когда кто-то мне пишет, что UB — ерунда, и что он много лет успешно пишет на С++, а остальные — просто неудачники, не понимающие язык, то я сразу считаю такого человека мастером.
Который никогда не допускает сравнения знаковых с беззнаковыми и, уж тем более, знакового переполнения в своих программах.
Вот мне и интересно посмотреть на то, как именно мастер избегает подобных граблей. S>> Сам-то я вообще не программист CC>Разве?
Отож. Лет 20 тому ушёл из написания кода в написание презентаций, документов, и емейлов.
CC>Без template is_max, на порядки более прямолинейный и использующий только то, что нужно именно тут и сейчас.
template is_max — просто очень компактный пример, иллюстрирующий проблему. Шаблонный параметр там нужен для того, чтобы помешать заменить is_max на return value == INT_MAX.
Можно привести более длинный пример с конкретным int или long, страдающий от тех же особенностей.
CC>Я код пишу не для вакуума, а под конкретные требования, включающие и компилятор.
Тут дело не в "конкретных требованиях, включающих компилятор", хотя таким образом вы закладываете бомбу под следующее поколение разработчиков, которые будут рано или поздно вынуждены выкинуть устаревший компилятор и перейти на что-то такое, что поддерживается производителем. Как мы видим, даже ваш любимый компилятор прекрасно умеет злоупотреблять UB.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>Потом от check_and_abort_if_error отказались, быстренько прошлись по коду и оставили: S>
S>do_some_important_operation();
S>
S>Тем самым проигнорировали код ошибки, который возвращает do_some_important_operation.
Хоть в целом я и согласен с идеей иметь по умолчанию иммутабельность и nodiscard (и явным mut/discardable), но и в голом блокноте тоже не нужно писать код в наше время.
При рефакторинге (удалении) check_and_abort_if_error нужно было пройтись по всем местам её вызова и проверить, всё ли нормально будет, если удалить check_and_abort_if_error.
S>* в результате рефакторинга какая-то функция, которая была void, и которая не требовала внимания к себе (например, бросала исключения при проблемах): S>
S>complete_current_operation();
S>
S>была преобразована и стала возвращать признак своей успешности. Т.е. теперь надо бы контролировать ее: S>
S>if(const auto r = complete_current_operation(); !r) {...}
S>
S>но это не было сделано.
Также нужно было пройтись по всем вызовам complete_current_operation.
S>* функция/метод возвращает RAII объект, который следовало бы сохранить. Если этого не сделать, то деструктор объекта тут же откатит изменения.
Вот это уже реальный аргумент в пользу nodiscard.
S>
S>std::make_unique<my_data>(...);
S>
S>объект создался и тут же уничтожится. S>В реальности с этим поведением могут быть связаны более сложные случаи. Например, у нас в SO-5 вызов send_periodic возвращает timer_id. Если этот timer_id не сохранить, то периодическое сообщение сразу же будет отменено. Поэтому если у кого-то было в коде: S>
S>то это приведет к ошибочному поведению именно из-за того, что возвращаемое значение было потеряно.
Косяк в дизайне API налицо. Если для send_delayed знать возвращаемое значение не нужно, а для send_periodic оно критично, то следовало бы делать `create_periodic(...).send()` или что-то в этом духе — чтобы уже по названию функции было понятно, что здесь не тривиальная отсылка сообщения, а создание объекта, которым требуется управлять.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, CreatorCray, Вы писали:
S>Боюсь, проблема не только в сайте
Проблема в твоих руках
S>Вы избавились от UB, и теперь ваш код работает неправильно всегда, даже в -O0: S>https://godbolt.org/z/ToKv8Kx3d
Ты не сумел скопировать правильно:
У тебя: return (std::make_unsigned_t<signed_integral> (value) + 1) < value;
А надо: return signed_integral (std::make_unsigned_t<signed_integral> (value) + 1) < value;
CC>>А кого будем считать мастером? Тут мнения очень сильно расходятся. S>Я верю людям на слово.
Зря.
S>я сразу считаю такого человека мастером.
А при чём тут вера на слово? Этож ты считаешь а не тот человек.
S> Поэтому когда кто-то мне пишет, что UB — ерунда
А где тебе написали конкретно что "UB — ерунда"?
S> и что он много лет успешно пишет на С++, а остальные — просто неудачники, не понимающие язык
Всё всегда оценивается по практическому выхлопу.
Если ударяться в странные конструкции и потом бороться со странностями compile time вычислений — то гемора будет побольше.
Если придерживаться KISS и писать просто и строго по делу, не растекаясь шаблонами по шаблонам — таких проблем не будет.
S>Который никогда не допускает сравнения знаковых с беззнаковыми
Постоянно и осознанно допускаю
S> и, уж тем более, знакового переполнения в своих программах.
Знакового точно никогда не было.
Беззнаковое осознанно используется в имплементации длинной математики.
S>Вот мне и интересно посмотреть на то, как именно мастер избегает подобных граблей.
Не ударяюсь в метапрограммирование. См ниже.
S>template is_max — просто очень компактный пример, иллюстрирующий проблему.
Проблема твоя в compile time вычислениях, которые работают совсем не так как реальная машина, под которую генерится код. И работают они так потому, что написаны во frontend компилятора, который витает в абстракциях и perfect мире, а не в backend, который знает за платформу и как на ней работают разные типы.
Это архитектурный баг компиляторостроителей, который можно починить но никто не станет, ибо пуристы упрутся рогом.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали: CC>Проблема в твоих руках
Да, действительно, потерял при копи-пейсте.
S>>я сразу считаю такого человека мастером. CC>А при чём тут вера на слово? Этож ты считаешь а не тот человек.
CC>А где тебе написали конкретно что "UB — ерунда"?
Ну, например, поставили фейспалм на простое утверждение "UB, из которого язык состоит чуть менее, чем полностью".
Вот я вижу, что интовая арифметика используется примерно в каждой первой программе. То есть если покрасить исходный код более-менее любого проекта в красный там, где "возможно UB", то его будет больше, чем не красного. CC>Всё всегда оценивается по практическому выхлопу.
Отож. CC>Если ударяться в странные конструкции и потом бороться со странностями compile time вычислений — то гемора будет побольше.
Что вы называете "странными конструкциями"? Мы кагбэ просто взяли сложение и сравнение — чо уж тут странного-то?
Compile-time вычисления сами по себе штука хорошая, поскольку позволяют сильно улучшить перформанс программ без потери общности. Те самые zero-cost abstractions, ради которых люди и выбирают C++ вместо менее упоротых языков. CC>Если придерживаться KISS и писать просто и строго по делу, не растекаясь шаблонами по шаблонам — таких проблем не будет.
Ооо, мне нравится ваш задор. Давайте попробуем починить UB в функции, написанной просто и строго по делу, безо всяких шаблонов:
long avg(long a, long b, long c)
{
return (a+b+c)/3;
}
S>>Который никогда не допускает сравнения знаковых с беззнаковыми CC>Постоянно и осознанно допускаю
Ну, тем более.
CC>Знакового точно никогда не было.
Хм, и как же вы это проверяете?
CC>Беззнаковое осознанно используется в имплементации длинной математики.
Я так и думал. Когда вы писали "у меня точно такой же код", я сходу заподозрил, что у вас там беззнаковая арифметика.
Потому что знаковое представление для "длинных цифр" противоестественно, а также потому, что если бы вы внезапно попробовали применить знаковую арифметику, то налетели бы на UB практически сходу.
CC>Не ударяюсь в метапрограммирование. См ниже.
Метапрограммирование тут совершенно ни при чём. S>>template is_max — просто очень компактный пример, иллюстрирующий проблему. CC>Проблема твоя в compile time вычислениях, которые работают совсем не так как реальная машина, под которую генерится код.
Ничего подобного. Проблема — вовсе не в compile time, а в том, как компилятор трактует UB. Как раз у вас в предыдущей попытке compile-time вычисления прошли "честно", и получили правильный результат.
А перенос вычислений в рантайм заставил сработать оптимизацию, которая воспользовалась UB в полном соответствии со стандартом языка.
CC>Это архитектурный баг компиляторостроителей, который можно починить но никто не станет, ибо пуристы упрутся рогом.
Это интересная гипотеза, но она не подтверждается практикой.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
CC>>Проблема в твоих руках S>Да, действительно, потерял при копи-пейсте.
CC>>А где тебе написали конкретно что "UB — ерунда"? S>Ну, например, поставили фейспалм на простое утверждение "UB, из которого язык состоит чуть менее, чем полностью".
И сейчас поставлю, потому что категоричность сего утверждения фейспалмова чуть более чем полностью
Теперь твоя очередь объяснять как ты из моего фейспалма вытащил утверждение "UB — ерунда"
S>Вот я вижу, что интовая арифметика используется примерно в каждой первой программе.
Что именно ты тут понимаешь под "интовая арифметика"?
S>Что вы называете "странными конструкциями"?
метапрограммирование
S>Compile-time вычисления сами по себе штука хорошая, поскольку позволяют сильно улучшить перформанс программ без потери общности. Те самые zero-cost abstractions, ради которых люди и выбирают C++ вместо менее упоротых языков.
Вот только не надо забывать что compile-time вычисления работают НЕ по правилам платформы, под которую выполняется компиляция.
То, что ты в данном примере называешь UB — на самом деле очень даже defined behavior. Неожиданный — да, но не undefined.
S>
S>long avg(long a, long b, long c)
S>{
S> return (a+b+c)/3;
S>}
S>
А что именно ты тут считаешь UB? Переполнение знакового типа имеет очень даже defined поведение для платформы, и если погромист не знает что творит — это недостаток квалификации.
S>Когда вы писали "у меня точно такой же код", я сходу заподозрил, что у вас там беззнаковая арифметика.
А у меня абсолютно везде беззнаковая, кроме тех редких мест где знак именно что нужен.
S>Как раз у вас в предыдущей попытке compile-time вычисления прошли "честно", и получили правильный результат.
Потому что "оптимизатор" по какой то внутренней причине ниасилил свернуть формулу в символьном виде, сработал fallback path и он формулу посчитал внутри себя на таких же типах, на том же железе.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Sinclair, Вы писали:
S>А дальше компилятор делает второй ход: а раз в стандарте написано, что переполнение — это UB, то я могу делать что угодно, без оглядки на аппаратуру. S>И, например, заменяю всю эту функцию на return false, и попутно встраиваю её во все места использования, выбрасывая все ветки кода, управляемые этим условием. Даже при компиляции под конкретный интел, который ведёт себя вполне себе defined образом. S>Да, программа работает не так, как ожидал программист, но зато очень быстро. PROFIT! S>Как по мне, так это очень похоже на каких-нибудь хитрожопых юристов, которые находят лазейку в законах и доят государство.
В данном случае ты даёшь оценку своим фантазиям, бо архитектуры/компиляторы явно определяют своё поведение при переполнении.
Т.е. UB тут для стандарта в общем, но не для конкретной связки платформы и компилятора.
Т.е. можно подобрать такое кодирование, что в твоём коде будет UB именно для этой платформы, например, для обратного кодирования есть два нуля для знаковых чисел — 0000 и 1111, где при сравнении первый ноль меньше второго, и твоя программа закономерно поломалась, как и предостерегал стандарт.
А так-то "железные" вещи часто пишут на сях для конкретной платформы, конечно, в т.ч. UB-код с т.з. "общего" стандарта.
А для конкретной платформы никакое не UB.
==========
Вдогонку, обратный код был популярен на заре компьютеров, бо он дешевле в реализации, хотя и гемморойней как раз в деле переполнения.
Ну, дык, переполнять можно только беззнаковые и тогда будет счастье.
А так-то в обратном коде отрицание числа — это 1 такт (простая инверсия), где сложение, допустим, занимало 4 такта.
В той схемотехнике отрицание числа в дополнительном коде потребует тоже 4 такта, т.к. это или вычитание числа из 0-ля или инверсия с инкрементом.
Еще в обратном коде достаточен один сумматор, т.к. вычитание сводится к сложению с негативным числом, а в дополнительном коде требуется отдельный блок вычитателя, либо вычитать на том же сумматоре в две операции (сначала инверсия с инкементом, потом сложение), т.е. это будет уже 8 тактов.
Здравствуйте, vdimas, Вы писали:
V>В данном случае ты даёшь оценку своим фантазиям, бо архитектуры/компиляторы явно определяют своё поведение при переполнении.
Ошибаетесь. Я же привёл пример. Каким образом "явно определённое поведение" приводит к разнице между -O0 и -O2 для приведённого фрагмента? V>Т.е. UB тут для стандарта в общем, но не для конкретной связки платформы и компилятора.
То, что вы описываете, называется implementation-defined behavior.
Да, если бы целое переполнение было IDB, то вопросов бы было гораздо меньше. Но нет, это именно UB, и, в отличие от IDB, компилятор имеет право доопределять UB произвольным образом в каждом месте использования.
Что мы и наблюдаем в приведённом примере.
V>Т.е. можно подобрать такое кодирование, что в твоём коде будет UB именно для этой платформы, например, для обратного кодирования есть два нуля для знаковых чисел — 0000 и 1111, где при сравнении первый ноль меньше второго, и твоя программа закономерно поломалась, как и предостерегал стандарт.
Нет. Не угадали.
Программа прекрасно ломается на совершенно любой платформе. V>А так-то "железные" вещи часто пишут на сях для конкретной платформы, конечно, в т.ч. UB-код с т.з. "общего" стандарта. V>А для конкретной платформы никакое не UB.
V>==========
Общеизвестные трюизмы поскипаны.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.