Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>В коде без разницы, а под отладчиком очень большая разница — увидеть "-2" и "-1" или "4294967294" и "4294967295".
Кстати, есть ли гуйные отладчики, умеющие при наведении показывать такое в заданных альтернативных форматах?
Здравствуйте, T4r4sB, Вы писали:
R>>Классическая запись четко и яяно описана в стандарте языка. Все остальное — твои личные фантазии.
TB>Повторяю: синтаксическая корректность ещё не показатель приемлемости кода.
Повторяю: твоя личная картина мира не является основанием объявить код некорректным. Неприемлемым ты его можешь считать, но только для себя.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>А сколь часто такое встречается? Можно примеров?
Да каждый раз, когда надо массив проитерировать наоборот. Или проитерировать вперёд от 0 до N-3, подорвавшись, когда это N-3 вдруг становится слишком большим из-за того, что N стало слишком маленьким.
Whenever you mix signed and unsigned numbers you get trouble. The rules are just very surprising, and they turn up in code in strange places that correlate very strongly with bugs. Now, when people use unsigned numbers they usually have a reason. And the reason will be something like 'well, it can't be negative' or 'I need an extra bit'. If you need an extra bit, I am very reluctant to believe that you really need it, and I don't think that's a good reason. When you think you can't have negative numbers, you will have somebody who initializes your unsigned with minus two, and think they get minus two, and things like that.
It is just highly error prone.
I think one of the sad thing about the standard library is that the indices are unsigned whereas array indices are signed and you are sort of doomed to have confusion, and problems with that. There are far too many integer types, there are far too lenient rules for mixing them together, and it's a major bug source, which is why I'm saying stay as simple as you can, use [signed] integers till you really really need something else.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Евгений Музыченко, Вы писали:
SVZ>>В коде без разницы, а под отладчиком очень большая разница — увидеть "-2" и "-1" или "4294967294" и "4294967295".
ЕМ>Кстати, есть ли гуйные отладчики, умеющие при наведении показывать такое в заданных альтернативных форматах?
Хороший вопрос. Но как такое реализовать, чтобы было юзабельно — тут я
В Студии когда-то была возможность наскриптить визуализаторы для собственных типов данных.
Сохранилась ли такая возможность — не знаю.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, T4r4sB, Вы писали:
R>>"Классическая схема" не является догмой. И отход от нее не является показателем некорректности кода.
TB>Необходимость идти в обход и делать кулхацкерский заголовок цикла говорит о наличии трудностей, создаваемых беззнаковыми типами.
"Обходы", "трудности" и "кулхацкерцские заколовки" существуют только в твоем воображении.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?
С точки зрение перформанса, есть случаи, где беззнаковые немного лучше, и нет случаев, где знаковые лучше. Примеры пользы беззнаковых:
— замена деления на степень двойки на сдвиг. Включая неявное деление в i < container.size() - fused операция при сравнении и переходе: while (i > 0) или for ( i ; i < 10 ; i++ ) CMP и JCC выполняются как одна операция только для беззнаковых. нет, уже для любых
— обычные умножение/деление быстрее для беззнаковых
С точки зрения корректности, знаковые как бы ограждают от одного типа ошибок (отрицательное число -> переполнение), но вносят другие (отрицательное число -> выход за диапазон), шило на мыло.
Возможно польза лишь в универсальности — если отказаться от многообразия типов, то использовать только лишь знаковые легче, чем только лишь беззнаковые.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>А оценка того, насколько часто это требуется, будет?
Редко. Но ошибки с таким итерированием случаются.
ЕМ>С какой целью хоть OpenMP, хоть что другое, использует знаковые индексы?
Что значит "с какой целью"? Оно не умеет делать for с беззнаковыми. С какой целью люди используют for?
ЕМ>Вообще абсурдный аргумент. А преобразования на что? Если же главная цель — спасти себя от предупреждений компилятора, то их можно отключить.
Преобразования зачем? Чтобы на каждый обход картинки кастовать её размеры к искомому типу? Гораздо удобнее их хранить в подходящем типе.
ЕМ>И что здесь "внезапного"? Так всегда было, есть и будет. Для координат в пределах кадра — беззнаковые величины, для координат в абстрактной системе — знаковые.
Внезапно, потому что именно внезапно. Одна нейросеть не выдаёт отрицательных координат, а другая именно что внезапно их выдаёт. При этом это координатная система кадра в пикселях, а не какая-то другая.
ЕМ>На это есть преобразования типов.
Да, но зачем? Код становится тупо замусоренным этими преобразованиями. Я со временем пришёл от беззнаковым к знаковым.
лезает за пределы типа вверх и вниз
ЕМ>Тоже не в кассу, здесь разрядности типа хранения и типа обработки разные.
С одной стороны да, но с другой я просто не могу вычитать яркости. Яркость, размер объекта, размер коллекции, числ объектов — это всё положительные величины. Но ВНЕЗАПНО с ними надо проводить арифметическое операции, где есть и вычитание. И ты предлагаешь каждый раз кастовать типы. Ну, так себе решение.
ЕМ>Когда подобных операций много, и преобразования сильно загромождают — не вопрос. Я прежде всего о тех случаях, когда ничего подобного не происходит, но типы используются знаковые, тем более — в примерах книг и статей.
Здравствуйте, Stanislav V. Zudin, Вы писали:
ЕМ>>Кстати, есть ли гуйные отладчики, умеющие при наведении показывать такое в заданных альтернативных форматах?
SVZ>Хороший вопрос. Но как такое реализовать, чтобы было юзабельно — тут я
Если примитивно, то жестко заданные варианты для каждого типа — десятичное/шестнадцатиричное, знаковое/беззнаковое для целых, символ/целое для char, имя/значение для enum и т.п. Если гибко, то настраивать этот набор для типов или их характеристик.
Здравствуйте, Homunculus, Вы писали:
H>у нас может не быть вообще выбранных элементов. Какое значение тогда должен принять этот индекс? 65535? uint_max? Мне это кажется нелогичным и некрасивым. По мне так гораздо красивее в этом случае назначать ему "-1"
Это не "красивее", а просто "короче". Красивее будет что-нибудь вроде NoneSelected, а чему оно равно — отдельный вопрос. Но и в том, и в другом случае, если хоть в одном месте это спецзначение будет использовано для индексирования, случится одна и та же задница.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Это не "красивее", а просто "короче". Красивее будет что-нибудь вроде NoneSelected, а чему оно равно — отдельный вопрос. Но и в том, и в другом случае, если хоть в одном месте это спецзначение будет использовано для индексирования, случится одна и та же задница.
Что значит "использовано для индексирования"?
И это красивее, не потому что короче, а потому что именно красивее логически.
ЕМ> То, что подобные операции могут приводить к отрицательным смещениям, ничем не отличается от технической возможности обратиться к элементу с очень большим индексом
Только на беззнаковом индексе хрен ты отличишь "попали раньше" от "попали позже".
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Спросите математиков, зачем они делят числа на целые и натуральные, а не обходятся только целыми. Универсальнее же.
Да, давай узнаем, зачем нужно кольцо целых чисел и все ли свои операции с беззнаковыми ты выполняешь в моноиде натуральных чисел или регулярно выходишь за пределы в видео кастов к другим типам. Статистика будет?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Индекс массива в C/C++ не может быть отрицательным — это следует из определения массива. То, что подобные операции могут приводить к отрицательным смещениям, ничем не отличается от технической возможности обратиться к элементу с очень большим индексом, чтобы за счет переполнения попасть раньше начала массива. Тут просто нужно различать техническую возможность получить какой-то результат, и смысл применямой операции.
Ядро фильтра с радиусом r вполне естественно записать в форме:
for (int i = r; i < size - r; ++i)
for (int j = -r; j <= r; ++j)
sum += buf[r] * kernel[r];
++buf;