Size: a a a

2020 May 20
Блог*
Закон Каннингема: лучший способ найти ответ на интересующий тебя вопрос в Интернете — это выложить не сам вопрос, а неправильный ответ на него.

Что интересно, сам Уорд Каннингем авторство этого закона отвергает.
источник
2020 May 21
Блог*
Знаете, что меня раздражает? Люди, которые делают посты с хэштегом #mood и какой-то прикреплённой музыкой. Ну вот что эти люди хотят этим сказать?

Показать, какой сейчас у них настроение? А не проще ли сказать это, блин, словами?

Показать, что они сейчас слушают? Ну, для этого есть статусы, где можно указать трек или, на худой конец, его название.

Сделать пост ради поста? Да ради, сука, бога, только нахрена туда вставлять хэштег, который переводится как "настроение"? Они хоть вообще знают, что хэштеги несут семантическую нагрузку?

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

Абсолютно бессмысленная вещь. Бесит, аж горит.

#бомбёжкипост
источник
Блог*
источник
Блог*
#prog #rust #article

Обстоятельное эмпирическое изучение ошибок в реальных программах на Rust. Деление на safe/unsafe код действительно помогает, но все баги с излишней блокировкой были найдены в safe коде. Особенности Rust делают некоторые паттерны ошибок более вероятными, чем в других языках. Изучение этих паттернов позволило создать статические анализаторы, которые вскрыли ранее незамеченные ошибки.

Читайте, когда найдётся свободное время, статья объёмная.

cseweb.ucsd.edu/~yiying/RustStudy-PLDI20.pdf
источник
Блог*
#prog #rust #meme
источник
Блог*
названия крейтов be like...
источник
2020 May 22
Блог*
#prog #cpp

Для C++ существует такая вещь, как CppCoreGuidelines. Это набор рекомендаций и лучших практик, нацеленных на то, чтобы люди более эффективно (читай, менее ногострельно) использовали C++. Частью этих гайдлайнов является разработанный Гербом Саттером документ, описывающий формализацию времён жизни в C++ и позволяющий отлавливать использование висячих ссылок. Разумеется, от такого документа мало толку, если всё это проверять вручную, но есть lifetime profiler — форк clang, в котором реализован статический анализатор, работающий согласно документу выше. Его можно сбилдить самостоятельно и использовать локально только зачем, а можно открыть godbolt.org и использовать компилятор x86-64 clang (experimental -Wlifetime). Как же этот анализатор работает на практике?

Начну немного издалека. В стандартной библиотеке C++ есть тип string (аналог в Rust — String). Это изменяемая строка из символов в неопределённой кодировке, хранящая данные в куче (как правило, ибо стандарт не запрещает использовать small string optimisation, когда маленькие строки хранятся на стеке, а не в куче). Самое главное — это владеющий тип: когда значение типа std::string выходит из области видимости, память, выделенная под данные строки, удаляется. В отличие от Rust, этот тип является неявно копируемым (что логично, учитывая, что этот тип появился сильно раньше move semantics): когда std::string передаётся аргументом в функцию, в куче выделяется память под копию строки и в неё копируются данные этой строки. Это может заметно снизить производительность. Для того, чтобы избежать ненужных аллокаций, стоит передавать строку по ссылке.

Так что же, есть производительный способ работать со строками без лишних трат? Не совсем. У std::string есть метод substr, который возвращает подстроку с указанных позиций, но проблема в том, что этот метод возвращает std::string, то есть выделяет память в куче. Как-то не зирокост. Можно, конечно, передавать ссылку на строку и индексы, выделяющие подстроку, но это неудобно. Для решения этой проблемы в разных библиотеках — в том числе, в boost — делали свои собственные типы. Они являлись невладеющими строками и хранили в себе лишь ссылку на данные исходной строки и позицию подстроки. Они дёшево копируются, и выделить подстроку при помощи такого типа также очень дёшево: достаточно поменять пару индексов. В стандарте C++17 подобный тип наконец-то добавили в стандартную библиотеку — это string_view, определённый в заголовочном файле <string_view>. Аналогом этого типа в Rust выступает &str.

Так что, теперь всё хорошо как будто в C++ в принципе что-то может быть хорошо? К сожалению, нет. Так как string_view является семантически невладеющим указателем, он, как и любой невладеющий указатель, может стать висячим (dangling). Получить висячий string_view в C++ довольно просто, особенно если учесть, что string_view неявно конвертируется из string. Более того, присваивание ссылке может продлить время жизни временного объекта, но с string_view это не работает, потому что они не являются ссылками, поэтому можно в одно строке создать временную строку, присвоить её переменной типа string_view... И получить невалидный string_view, поскольку временная строка будет уничтожена в конце строки. Что ж, звучит как проблема, которую может отловить анализатор времён жизни!

Для начала напишем пару функций, оперирующих string_view:

#include <string>
#include <string_view>

using sv = std::string_view;

sv shortest(sv a, sv b) {
   return a.size() < b.size() ? a : b;
}

sv cut_prefix(sv prefix, sv str) {
   //
не спрашивайте
   if (str.rfind(prefix, 0) == 0) {
       return str.substr(prefix.size());
   } else {
       return str;
   }
}

Эти функции имеют одинаковые сигнатуры, но между ними есть большое отличие: shortest может вернуть любой из двух аргументов, а вот cut_prefix может вернуть только второй аргумент или подстроку из него.
источник
Блог*
Что ж, попробуем использовать -Wlifetime на практике:

sv example_should_err(int n, sv str) {
   auto n_str = std::to_string(n);
   return shortest(n_str, str);
}

sv example_should_ok(int n, sv str) {
   auto n_str = std::to_string(n);
   return cut_prefix(n_str, str);
}

На первый пример компилятор выдаёт предупреждение:

<source>:20:5: warning: returning a dangling pointer [-Wlifetime]
   return shortest(n_str, str);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~

<source>:20:5: note: pointee 'n_str' left the scope here
   return shortest(n_str, str);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~

И совершенно правильно, потому что тут может быть возвращён string_view, созданный из временной строки, которая уничтожается на выходе из функции. Что же касается второго примера... Тоже предупреждение. Причём то же самое :/ Хотя тут string_view от n_str заведомо не покидает пределы функции.

...Если посмотреть README к форку, можно увидеть ещё один флаг, -Wlifetime-filter. Цитирую: "Reduce the number of false-postives at the cost of additional false negatives.". Добавляем этот флаг и... Получаем тот же самый выхлоп.

Ну, ладно, это я испорчен растом, на самом деле тот факт, что компилятор C++ ловит подобные ошибки безо всяких аннотаций со стороны пользователя, пусть и с ложноположительными результатами — это довольно круто. Но что, если мы захотим передавать функцию отдельным параметром? Давайте проверим:

template <typename F> sv example_hof(int n, sv str, F func) {
   auto n_str = std::to_string(n);
   return func(n_str, str);
}

sv example_hof_should_ok(int n, sv str) {
   return example_hof(n, str, cut_prefix);
}

sv example_hof_should_err(int n, sv str) {
   return example_hof(n, str, shortest);
}

Кладём в компилятор и... Получаем ноль предупреждений.

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

sv example_hof(int n, sv str, sv (*func)(sv, sv)) {
   auto n_str = std::to_string(n);
   return func(n_str, str);
}

// example_hof_should_ok и example_hof_should_err остались без изменений

Проверяем... Ноль предупреждений.

Заключения не будет.
источник
2020 May 23
Блог*
#prog #rust и, пожалуй, #meme
источник
Блог*
Улучшал код typed_phy и случайно наткнулся на такое прекрасное...

Силой святой копипасты у меня получилось деление на 0 😅
источник
Блог*
#prog #meme
источник
Блог*
источник
2020 May 25
Блог*
#prog #article

Как сделать из notepad.exe экран для рендера трёхмерных изображений с FPS 30.

kylehalladay.com/blog/2020/05/20/Rendering-With-Notepad.html
источник
Блог*
dereference_pointer_there
#prog #article

Как сделать из notepad.exe экран для рендера трёхмерных изображений с FPS 30.

kylehalladay.com/blog/2020/05/20/Rendering-With-Notepad.html
Результат
источник
Блог*
#meme

(thanks @trubad)
источник
Блог*
#prog #rust #meme
источник
Блог*
источник
Блог*
#prog #cpp

В C++ в наследство от C достались операторы инкремента и декремента (++ и --). Как и любые операторы, их можно перегружать для своих типов. Но есть один нюанс: как различать префиксный и постфиксный инкременты? В C++ решение таково: префиксный оператор не принимает аргументов, а постфиксный принимает неиспользуемый параметр типа int.

Если это не костыль, то я даже не знаю, как это назвать.

stackoverflow.com/questions/15244094/c-overloading-for-both-pre-and-post-increment
источник
2020 May 26
Блог*
Хочу основать конференцию "Переносица". Чтобы никогда её не организовывать и всё время писать объявления ""Переносица" переносится".
источник
Блог*
dereference_pointer_there
Хочу основать конференцию "Переносица". Чтобы никогда её не организовывать и всё время писать объявления ""Переносица" переносится".
О да 😈 (от подписчика)
источник