Re[7]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 15:40
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP> for(int i=INT_MAX-2; i>=0; ++i) {

EP> cout << i << " ";
EP> }

EP>Таки закольцевался int, правда jmp'ом


Да, такое они ловят. Видимо, предсказание на сколько-то итераций вперёд.

Ну я давно говорю, что семантика переполнения должна быть управляема контекстом — и ни знаковая с "программист должен сам", ни беззнаковая с модулем не должны быть единственными, а умолчанием вообще должна быть неотложная генерация ошибки.
The God is real, unless declared integer.
Re[8]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 16:00
Оценка:
Здравствуйте, netch80, Вы писали:

EP>> for(int i=INT_MAX-2; i>=0; ++i) {

EP>> cout << i << " ";
EP>> }
EP>>Таки закольцевался int, правда jmp'ом
N>Да, такое они ловят. Видимо, предсказание на сколько-то итераций вперёд.

Здесь видимо следующая логика: i не отрицательное, и только инкрементируется, следовательно отрицательным без прохода по UB оно никак стать не может, поэтому имеем право заменить i>=0 на true.
Не думаю что зависит от количества итераций. Ибо даже если начинать с i=0 — в генерируемом коде всё равно безусловный jmp.
А поставил я INT_MAX-2 лишь для наглядности, чтобы был виден переворот в печатаемых значениях в отрицательные.

N>Ну я давно говорю, что семантика переполнения должна быть управляема контекстом — и ни знаковая с "программист должен сам", ни беззнаковая с модулем не должны быть единственными,


Там где скорость не важна — очевидно можно решить пользовательскими типами, а-ля safe int, saturated int, etc. Там где важна — нужна поддержка железа.

N>а умолчанием вообще должна быть неотложная генерация ошибки.


Было бы неплохо. Например как trap при делении на ноль.
Отредактировано 09.05.2020 16:06 Evgeny.Panasyuk . Предыдущая версия .
Re[9]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 17:02
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здесь видимо следующая логика: i не отрицательное, и только инкрементируется, следовательно отрицательным без прохода по UB оно никак стать не может, поэтому имеем право заменить i>=0 на true.

EP>Не думаю что зависит от количества итераций. Ибо даже если начинать с i=0 — в генерируемом коде всё равно безусловный jmp.

Да, согласен. Я забыл, что в неудачном варианте было i>0, и не проверил этот от нуля.
У GCC, -O2 и выше без -fno-strict-overflow приводит к удалению проверки.
У Clang, -Og уже достаточно для такого эффекта.

N>>Ну я давно говорю, что семантика переполнения должна быть управляема контекстом — и ни знаковая с "программист должен сам", ни беззнаковая с модулем не должны быть единственными,


EP>Там где скорость не важна — очевидно можно решить пользовательскими типами, а-ля safe int, saturated int, etc. Там где важна — нужна поддержка железа.


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

N>>а умолчанием вообще должна быть неотложная генерация ошибки.

EP>Было бы неплохо. Например как trap при делении на ноль.

Ну этот trap в Unix неудобно ловить.
Я предпочитаю явное исключение (C++) или простановку флага.
The God is real, unless declared integer.
Re[10]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 17:48
Оценка:
Здравствуйте, netch80, Вы писали:

N>Поддержка железа давно доступна в нормальных компиляторах


Я имел в виду около-бесплатную железную поддержку на happy path, то есть без необходимости жонглирования флагами в asm, постоянной их проверкой, а посредством вызова установленного обработчика если вдруг произошло переполнение.
Re[4]: Откуда эта лютая любовь к знаковым целым?
От: PM  
Дата: 09.05.20 18:57
Оценка: +1
Здравствуйте, netch80, Вы писали:

H>>>Во-вторых, иногда нужно не-валидное значение чего-то, что по смыслу неотрицательно. И для этого я лично использую «-1». И если переменная равна ему, то значит значение невалидное. Такая штука с unsigned не проканает, если не вводить всякие magic digits конечно.

PJ>>std::optional<uint>

N>И терять 4-8 байт вместо одного бита ;[


Можно и не терять, если есть возможность использовать какое-то сигнальное значение: https://github.com/akrzemi1/markable

using namespace ak_toolkit;
typedef markable<mark_int<int, -1>> opt_int;

opt_int oi;
opt_int o2 (2);

assert (!oi.has_value());
assert (o2.has_value());
assert (o2.value() == 2);

static_assert (sizeof(opt_int) == sizeof(int), "");
Re: Офтоп
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 09.05.20 19:07
Оценка: +2
Ну вот какой добрый человек тему перенёс? Как мне теперь определить, что я читал, а что — нет?
Маньяк Робокряк колесит по городу
Re[11]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 20:08
Оценка: 1 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

N>>Поддержка железа давно доступна в нормальных компиляторах


EP>Я имел в виду около-бесплатную железную поддержку на happy path, то есть без необходимости жонглирования флагами в asm, постоянной их проверкой, а посредством вызова установленного обработчика если вдруг произошло переполнение.


z/Arch: ставишь PSW бит 20 в единичку и любое переполнение в арифметической команде даёт немедленное исключение. Для адресной и прочей беззнаковой арифметики используется другой набор команд (типа, ALR вместо AR), но тогда у тебя не будет немедленного статуса типа "<0".

MIPS: зовёшь какую-нибудь add вместо addu, и даже битика режима не надо ставить.

Но в нормальных современных процессорах, даже если есть проверки на happy path, за счёт предсказания ветвлений оно в подавляющем большинстве случаев пролетает их сходу, не притормаживая.
The God is real, unless declared integer.
Re[7]: Откуда эта лютая любовь к знаковым целым?
От: wander  
Дата: 09.05.20 20:16
Оценка: +2
Здравствуйте, rg45.

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


Это бесполезно. Ты ничего от него не добьешься
Он воспринимает язык как набор костылей, часть функций которого вообще не пойми зачем нужны.

И чтобы предупредить заранее возможные неправильные интерпретации, сразу скажу: что мой пост касается только утверждений по поводу якобы "кулхацкерских" возможностей цикла for при полном игнорировании того, что эти возможности были изначально в дизайне языка. Это все равно, что ругать какой-нибудь внедорожник за его дополнительные возможности, которых нет у других, "типичных", автомобилей. "Извольте, добрый сер, если застряли, вызывать эвакуатор, как все нормальные люди, а не вытягивать самого себя лебедкой с помощью дерева".

По вопросу знаковых\беззнаковых индексов предпочту воздержаться от комментариев.
Отредактировано 09.05.2020 20:27 wander . Предыдущая версия .
Re[8]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 09.05.20 20:58
Оценка: +3
Здравствуйте, wander, Вы писали:

W>И чтобы предупредить заранее возможные неправильные интерпретации, сразу скажу: что мой пост касается только утверждений по поводу якобы "кулхацкерских" возможностей цикла for при полном игнорировании того, что эти возможности были изначально в дизайне языка.


Изначальный дизайн языка, говоришь?
Вот код, который честно использует возможности языка, нравится такое читать?
switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
               } while (--n > 0);
    }

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

W>Это все равно, что ругать какой-нибудь внедорожник за его дополнительные возможности, которых нет у других, "типичных", автомобилей. "Извольте, добрый сер, если застряли, вызывать эвакуатор, как все нормальные люди, а не вытягивать самого себя лебедкой с помощью дерева".


Это как ругать собранный на коленке самодельный автомобиль за то, что в его конструкции есть наклейки СПАРКО, сабвуфер в багажнике и колхозный ксенон. Да, извольте на ДОПах светить теми фарами, которые не слепят встречных водителей.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 09.05.2020 21:02 T4r4sB . Предыдущая версия .
Re[11]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 09.05.20 21:34
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ты всё ещё предпочтёшь воротить нос от стандартной и лаконичной идиомы


Я такую лаконичность сишную в гробу видал.
Это говно, а не лаконичность.
Лаконичность — это
reverseFor (i: n-1 .. 0);


EP>в пользу более сложного выражения, в котором проще допустить ошибку, которое работает только со знаковыми, из-за субъективной "костыльности" стандартной идиомы?


Фариант с фором гораздо более универсален. А вот ваш вайл с беззнаковыми придётся мутить по-особому для перебора от n-3 до m например.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[9]: Откуда эта лютая любовь к знаковым целым?
От: wander  
Дата: 09.05.20 21:42
Оценка: +1
Здравствуйте, T4r4sB, Вы писали:

TB>Изначальный дизайн языка, говоришь?

Говорю.

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

TB>
TB>switch (count % 8) {
TB>    case 0: do { *to = *from++;
TB>    case 7:      *to = *from++;
TB>    case 6:      *to = *from++;
TB>    case 5:      *to = *from++;
TB>    case 4:      *to = *from++;
TB>    case 3:      *to = *from++;
TB>    case 2:      *to = *from++;
TB>    case 1:      *to = *from++;
TB>               } while (--n > 0);
TB>    }
TB>

Duff`s Device, ага.
Правда я вот больше 20 лет пишу на С и С++ (и не только), и код подобный либо в специальных "инкубаторах" видел, либо в таких вот темах на форуме.
А код с комбинированием операций в секции for встречается постоянно. И ты вообще второй человек в моей жизни, которого это *так* раздражает.
Что характерно первый, как и ты, в C++ пришел из паскалеподобных языков.
Короче говоря, этот пример никак не влияет на то, что концепция цикла for изначально предусматривает его гибкое использование
и не может по определению называться "хакерством".
"Хакерством", например, можно было бы называть метапрограммирование на шаблонах. Duff`s Device — тоже под это подходит, т.к.
использует побочный эффект от того, что метка в С\С++ не вводит области видимости. А c for все нормально.

TB>Так вот, изначальный дизайн — говнище, и народ нашёл распространённые практики, что из этого дизайна таки пригодно к употреблению

Вкусовщина.

TB>мамкины хацкеры продолжают заниматься мозговым онанизмом...

Ты не забыл, что в приличном обществе находишься?
Re[10]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 09.05.20 22:26
Оценка: :)
Здравствуйте, wander, Вы писали:

W>Что характерно первый, как и ты, в C++ пришел из паскалеподобных языков.


Ну правильно, пока паскалисты писали простенькие, но рабочие лабы, сишники понтовались очередным бессмысленным способом написать алгоритм через задницу.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: CreatorCray  
Дата: 09.05.20 23:29
Оценка:
Здравствуйте, Marty, Вы писали:

M>Писать зело больше

int -> uint?

M>Про отрицательные значения и то, что они не используются — ты не можешь быть уверен. Но таки да, может и по лени или недосмотру.

Ну не бывает отрицательного размера памяти
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Ой, да ладно.
От: CreatorCray  
Дата: 09.05.20 23:29
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>#define counter unsigned int;

S>
S>for (counter i = 0; i < X; i++)

... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[4]: Ой, да ладно.
От: Sheridan Россия  
Дата: 10.05.20 00:27
Оценка:
Здравствуйте, CreatorCray, Вы писали:

S>>#define counter unsigned int;

S>>for (counter i = 0; i < X; i++)

CC>


Ох уж эти милые любители фигурных цитат
Matrix has you...
Re[12]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 10.05.20 00:44
Оценка:
Здравствуйте, netch80, Вы писали:

N>z/Arch:

N>MIPS:

О, интересно, не знал что где-то есть.

N>Но в нормальных современных процессорах, даже если есть проверки на happy path, за счёт предсказания ветвлений оно в подавляющем большинстве случаев пролетает их сходу, не притормаживая.


Ну это совсем не бесплатно — арифметика используется повсеместно, в таком варианте её предсказания займут приличный кусок таблицы предсказателя, тормозя всё остальное приложение. На небольших по размеру горячих циклах проблемы нет, но на развесистых итерациях будет проседание.
Re[12]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 10.05.20 01:13
Оценка: +1
Здравствуйте, T4r4sB, Вы писали:

EP>>Ты всё ещё предпочтёшь воротить нос от стандартной и лаконичной идиомы

TB>Я такую лаконичность сишную в гробу видал.
TB>Это говно, а не лаконичность.
TB>Лаконичность — это reverseFor (i: n-1 .. 0);

Видимо мы как-то по-разному понимаем слово "лаконичность":
reverseFor(i: n-1 .. 0)
vs
while(n--)



EP>>в пользу более сложного выражения, в котором проще допустить ошибку, которое работает только со знаковыми, из-за субъективной "костыльности" стандартной идиомы?

TB>Фариант с фором гораздо более универсален. А вот ваш вайл с беззнаковыми придётся мутить по-особому для перебора от n-3 до m например.

Ну так и замечательно, но вот для обсуждаемого конкретного частного случая while(n--) отлично подходит.
И этот вариант нужно знать, даже если сам не используешь — чтобы моментально парсить сторонний код, где это таки используется. А раз всё равно знаешь — то почему бы не использовать самому?
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 10.05.20 01:44
Оценка: +1
Здравствуйте, kov_serg, Вы писали:

_>ps: меня больше огорчает всеобщее пристрастие к условию выхода из цикла for(size_t i=0;i!=end;++i){} где исключается одна точка, вместо for(size_t i=0;i<end;++i){} где запрещаются все недопустимые значения.


1. Если там какой-то баг, из-за которого запрещение всех недопустимых значений даёт другой результат нежели исключение точки — то лучше чтобы он проявился как можно раньше, при тестировании, а не молча проглатывался всё время.
Если действительно хочется дополнительно подложить соломки, то намного лучше использовать i!=end, плюс assert(i<end); в начале тела цикла.

2. Не все типы имеющие opreator!=, имеют operator< — особенно важно в обобщённом коде.
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 10.05.20 02:10
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Беззнаковость в STL — это огромная историческая ошибка, даже Степанов это признал.


А есть цитата Степанова на эту тему?
Кое-что есть на эту тему в его Notes on Programming, но не то о чём ты говоришь.
Re[5]: Ой, да ладно.
От: CreatorCray  
Дата: 10.05.20 02:56
Оценка: +1
Здравствуйте, Sheridan, Вы писали:

S>>>#define counter unsigned int;

S>>>for (counter i = 0; i < X; i++)
CC>>

S>Ох уж эти милые любители фигурных цитат

Да там одного define достаточно чтобы зафейспалмить.
С "for" просто нагляднее.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.