1.83K subscribers
3.29K photos
130 videos
15 files
3.56K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
И ещё немного скриншотов
3
Forwarded from shitposting 3.0 [+ dragons]
🤯10👍1😁1😍1
#meme про обнимашки
Forwarded from PUSSY MEMES
😢187🤮1
🌚6😁2
#meme злободневный
Forwarded from shitposting 3.0 [+ dragons]
👍12🌚3😁1😢1
Forwarded from shitposting 3.0 [+ dragons]
😁163
Forwarded from shitposting 3.0 [+ dragons]
👍6😁3💯2
❤‍🔥7🌚3🖕2
#prog #rust

TIL что у типов Ipv4Addr/Ipv6Addr есть ассоциированные константы LOCALHOST и UNSPECIFIED, а у Ipv4Addr есть ещё и BROADCAST.
3
Блог*
#prog Tini — init-процесс, который только завершает зомби-процессы и корректно пробрасывает сигналы — и больше ничего не делает. Используется главным образом внутри Docker.
#prog #article

Introducing dumb-init, an init system for Docker containers — рассказывает о том, для чего в принципе нужны dumb-init и tini.

TL;DR: если вы не спавните init-процесс как первый процесс внутри контейнера, то контейнер почти наверняка работает неправильно касательно реагирования на сигналы и завершения зомби-процессов.
#prog #rust

Diagnostic namespace

TL;DR: в nightly теперь есть (за #[feature], разумеется) атрибут #[diagnostic::on_unimplemented], который позволяет прицепить свою дополнительную информацию к ошибке о том, что тип не реализует трейт. Этот атрибут уже используется в axum и diesel.
🔥7
Если я выгляжу страшно красиво, это считается за хеллоуинский костюм?

If I look drop-dead gorgeous, does it count as a Halloween costume?
😁10
#prog #cpp

От Chandler Carruth есть доклад "Garbage In, Garbage Out: Arguing about Undefined Behavior with nasal demons". В нём он рассказывает о конструктивных подходах к обсуждению UB и приводит примеры, как UB может сказаться на генерируемом коде.

В частности, на 39:19 он показывает пример со следующим кодом:

bool compare(uint32_t i1, uint32_t i2,
uint8_t* block) {
uint8_t c1, c2;

/* 1 */
c1 = block[i1]; c2 = block[i2];
if (c1 != c2) return c1 > c2;
i1++; i2++;

/* 2 */
c1 = block[i1]; c2 = block[i2];
if (c1 != c2) return c1 > c2;
i1++; i2++;
...

Код генерировался под 64-битную платформу. По словам Чендлера, проблема заключается в том, что индексы имеют беззнаковый тип. В C и C++ переполнение беззнаковых чисел определено и имеет модулярную семантику. Это сказывается на генерируемом коде: во втором блоке сначала происходит вычисление нужного смещения через lea — которое приведёт индекс к нулю при переполнении — и только потом индекс используется в mov для доступа к памяти.

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

Из зала было справедливое замечание, что в данной ситуации правильнее было бы использовать size_t. Чендлер на это ответил довольно развёрнуто, но одним из пунктов в его ответе было то, что size_t — беззнаковый тип и потому страдает от той же пессимизации кода.

Звучит складно и вроде как вполне резонный аргумент в пользу UB для переполнения на интах. Так что я решил увидеть эффект своими глазами на godbolt.

И... Я его не увидел.

Более того, я решил написать вариант, где индексы i1 и i2 имели тип size_t. И в этом якобы неэффективном варианте модулярной арифметики не было.

Код на godbolt

Эффект соблюдается и при увеличении числа блоков до шести.

В связи с этим у меня два вопроса:

1. Почему компилятор не эксплуатирует UB, связанное с переполнением знаковых чисел, и всё равно использует модулярную арифметику? (это вопрос скорее к GCC, потому что clang успешно проводит эту оптимизацию).

2. Почему и GCC, и clang не используют модулярную арифметику для size_t, не смотря на то, что это, вообще говоря, смена наблюдаемого поведения? У меня есть предположение, что это связано с переполнением указателей, которое тоже является UB (переполнение любой инкрементации означало бы, что читается память по указателю block + SIZE_MAX, а чтение по такому указателю не является валидным, поскольку все объекты в памяти не больше SIZE_MAX по определению и указатель, сформированный таким образом, будет one past end даже самого большого объекта).
🤔3👍1
Forwarded from HORNYPOSTING 🤤
😁9🤯1
😒🤚 Нейросеть
😏👉 Нейроудочка
😁4