1.83K subscribers
3.24K photos
127 videos
15 files
3.52K links
Блог со звёздочкой.

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

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Блог*
Ради чего вы подписаны на канал?
Всем новоподписавшимся предлагаю пройти опрос
C++20 has has me me seeing seeing double double

#prog #cpp
twitter.com/slurpsmadrips/status/1266080792012140545
Блог*
C++20 has has me me seeing seeing double double #prog #cpp twitter.com/slurpsmadrips/status/1266080792012140545
#prog #cpp

И это не бессмыслица, как может показаться с первого взгляда.

Что означает noexcept(noexcept(iter.dereference()))? Это одинаковые имена для разных вещей.

Первое использование noexcept — это noexcept specifier, который является частью типа функции (но не участвует в перегрузке, т. е. две функции не могут отличаться только этим) и описывает, бросает ли функция исключения. Если исключение должно покинуть noexcept функцию, вместо этого вызывается std::terminate, что обычно означает завершение работы программы. После ключевого слова noexcept в скобках может стоять константное булево выражение. В этом случае то, является ли функция не-бросающей-исключения, зависит от того, во что это выражение вычисляется. Это полезно, если функция шаблонная и она пробрасывает исключения из внешних функций.

Второе использование noexcept — это noexcept operator. Он применяется к выражению в скобках и возвращает, является ли выражение noexcept (в смысле спецификации noexcept). Этот оператор можно использовать везде, где требуется выражение булевого типа, но чаще всего он используется вкупе с noexcept specifier. Таким образом, сложив два и два, получаем, что noexcept(noexcept(iter.dereference())) означает, что функция dereference не бросает исключения только в том случае, если метод iterator_type::dereference не бросает исключения.

Что же за история с requires requires? Тут ситуация похожая, но несколько более сложная.

Первое употребление requires относится к require clause. Это, гм... Спецификатор? ...Который принимает константное булево выражение и запрещает инстанцирование шаблона, если выражение вычисляется в false. Это фича предназначается для раннего отсечения неправильного использования шаблонов, раньше, чем инстанцирование будет сделано до конца. Принципиально эта фича, строго говоря, не добавляет нового функционала, поскольку подобные проверки можно было делать и раньше с использованием идиомы SFINAE (тот же std::enable_if), но использование requires приводит к куда более ранним диагностикам и, как следствие, более понятным сообщениям об ошибках.

Второе употребление requires относится к requires expression. Это оператор, который применяется к, гм, "requirement-seq" (это кусок синтаксиса с грамматикой, отличающейся от грамматики C++) и отвечает на вопрос, является код после него well-formed — т. е. компилируется ли он вообще. Как и оператор noexcept, этот оператор может быть использован всюду, где ожидается булево выражение. В итоге мы получаем, что requires requires { iter.dereference(); } означает "эта специализация шаблона определена только тогда, когда на переменной iter можно вызвать метод dereference (и это не приведёт к ошибке компиляции)".

Дополнительное чтение: вопрос на Stack Overflow про requires requires.
Блог*
C++20 has has me me seeing seeing double double #prog #cpp twitter.com/slurpsmadrips/status/1266080792012140545
Лучшая реакция (моего знакомого) на этот твит: "Да-да".

А ещё, пока я писал этот пост, на канале появился 333 подписчик, ура!
(Почему я не писал про это тогда, когда подписчиков было действительно 333? Потому что в число этих подписчиков вхожу и я сам)
⬇️ шутка про borrow checker
Forwarded from Идеи неинтересных фильмов
Железный человек сражается со злейшим врагом - ржавчиной.
#prog #rust #article

Очередной наброс на тему Rust. Как всегда, всё самое интересное — в комментариях.

habr.com/ru/post/504622/
#prog #go #menacingopensource

Для Go есть пакет filter. Это реализация некоторых FP-like примитивов, написанных самим Робом Пайком. Как он сам пишет в README:

"I wanted to see how hard it was to implement this sort of thing in Go, with as nice an API as I could manage. It wasn't hard.

Having written it a couple of years ago, I haven't had occasion to use it once. Instead, I just use "for" loops.

You shouldn't use it either."

Внутри есть всё то, что мы так любим в Go: interface{}, рефлексия, отсутствие ленивости, захардкоженность слайсов. Но, конечно, вишенка на торте — это единственный PR, который так и не был смержен, и реакция Пайка на него.

github.com/robpike/filter
#prog #article

Csmith — программа для генерации случайных программ на C. Отличается от остальных подобных программ тем, что сгенерированные программы не содержат неопределённого поведения. Использование Csmith позволило обнаружить несколько сотен багов в GCC и LLVM. О структуре Smith и о достигнутых с её помощью результатов подробно изложено в статье — к сожалению, довольно старой, от 2011 года.

Несколько интересных подробностей:
1) Из всех протестированных компиляторов CompCert был единственным, в котором не было багов мидл-енда, приводящих к неправильной компиляции кода. Формальная верификация работает!
2) Абзац про тестирование коммерческих компиляторов настолько хорош, что я процитирую его целиком:
"Experience with commercial compilers
There exist many more commercial C compilers than we could easily test. The ones we chose to study are fairly popular and were produced by what we believe are some of the strongest C compiler development teams. Csmith found wrong-code errors and crash errors in each of these tools within a few hours of testing.
Because we are not paying customers, and because our findings represent potential bad publicity, we did not receive a warm response from any commercial compiler vendor. Thus, for the most part, we simply tested these compilers until we found a few crash errors and a few wrong-code errors, reported them, and moved on."

Csmith на GitHub
#prog #article

Для облегчения симптомов синдрома самозванца: "Я выпустил текстовый процессор, форматировавший жёсткий диск после каждого 1024-го сохранения".

Оригинал (в виде треда в твиттере, так что читать не очень удобно)
Перевод на Хабре
#prog #rust #rustlib

Иногда бывает полезным не использовать порядок, определённый на типе при помощи Ord, а использовать порядок, заданный некой внешней сущностью. Крейт comparator даёт интерфейс Comparator<T> с методом compare(&self , &T, &T) -> Ordering. Само по себе это не очень интересно, но на базе этой абстракции можно построить уже непосредственно полезные сущности. В частности — то, что предоставляет сам крейт, бинарную кучу с порядком на элементах, заданных компаратором.

Как известно, куча из std Rust является максимальной кучей, т. е. на вершине лежит максимальный элемент. Для того, чтобы сделать минимальную кучу, приходится оборачивать элементы в std::cmp::Reverse. Это не только не очень удобно, но и лишает возможности за константное время превратить кучу в вектор. В случае с кучей из comparator такой проблемы не возникает, потому что можно легко сделать кучу с обратным порядком:

use comparator::reverse_order;
use comparator::collections::BinaryHeap;

let mut heap = BinaryHeap::with_comparator(reverse_order());

К сожалению, это, в сущности, всё, что есть в comparator, а последнее обновление было год назад. С другой стороны, даже в текущем виде крейт полезен, поэтому я и решил о нём рассказать.

comparator на crates.io
Документация
Forwarded from rusta::mann
Сегодня написал на автомате make_unique::<Name>() на C++, и долго не мог понять почему компилятор кричит что-то про неймспейсы на турборыбу.
#prog #quotes (заново, потому что без контекста хуже понятно)
Forwarded from xor eax, eax
Как раст ходит по типам в данном случае?


trait SomeType {}

struct Test<T: ?Sized>(core::marker::PhantomData<T>);

impl<T: ?Sized + SomeType> Test<T> {
const FOO: bool = true;
}

trait Fallback {
const FOO: bool = false;
}

impl<T: ?Sized> Fallback for T {}

Test::<$ty>::FOO
Forwarded from вафля 🧇🍓
раст ходит так: топ топ топ (извините)
#prog #rust #rustreleasenotes #politota

Выпущена новая версия Rust: 1.44.0! Изменений не так много, самое значимое — asycn/await более не требует thread-local storage и потому может быть использован в #[no_std]. К сожалению, ввиду недавних событий в США, а также мнения Rust core team, что "tech is and always will be political", внятного описания новых фич в блогопосте нет, так что лучше сразу раздел в RELEASES.md открыть.

Блогопост
Подробные заметки о релизе