Forwarded from мне не нравится реальность
Помните scoped threads из crossbeam, которые позволяют спавнить не
В
'static
функции (замыкания, которые захватывают что-то по ссылке)?В
std
скоро(™) собираются такое добавить: <twitter:m_ou_se>#prog #cpp #abnormalprogramming
twitter.com/sehetw/status/1465726704979267586
Вообще это было переслано в <twitter:Affective C++>, но прикольно, что на C++ можно до некоторой степени сымитировать именованные прерывания цикла
twitter.com/sehetw/status/1465726704979267586
Вообще это было переслано в <twitter:Affective C++>, но прикольно, что на C++ можно до некоторой степени сымитировать именованные прерывания цикла
Twitter
sehe
@sehetw @HenryKSloan @AffectiveCpp Alternatively, make it more generic godbolt.org/z/hqWoKszq9
#prog #cpp #article
shared_ptr<T>: the (not always) atomic reference counted smart pointer
Статья о том, как shared_ptr может использовать не атомарные инкременты (и некоторые спекуляции на тему того, является ли это вообще безопасным)
shared_ptr<T>: the (not always) atomic reference counted smart pointer
Статья о том, как shared_ptr может использовать не атомарные инкременты (и некоторые спекуляции на тему того, является ли это вообще безопасным)
snf.github.io
shared_ptr<T>: the (not always) atomic reference counted smart pointer · Snf's blog
Forwarded from Alex Gualse's posts
A lot of fonts show letter
If you somewhere use any fonts, take care about they have different
I
and l
very similar and it's wrong.If you somewhere use any fonts, take care about they have different
I
and l
especially where there is user input (like about yourself, post texts, etc)#article
Статья (перевод) от основателя Signal с впечатлениями от так называемого web3.
TL;DR: реалии этих проектов противоречат декларируемым ценностям (главным образом децентрализации) и вообще катастрофически сломаны.
Статья (перевод) от основателя Signal с впечатлениями от так называемого web3.
TL;DR: реалии этих проектов противоречат декларируемым ценностям (главным образом децентрализации) и вообще катастрофически сломаны.
Moxie Marlinspike
My first impressions of web3
Despite considering myself a cryptographer, I have not found myself particularly drawn to “crypto.” I don’t think I’ve ever actually said the words “get off my lawn,” but I’m much more likely to click on Pepperidge Farm Remembers flavored memes about how…
запуск завтра
Извините, что ночью, но исследователи утверждают, что Pegasus стабильно взламывает самую последнюю версию айфона (14.6). Без всяких кликов по ссылкам, просто посылают жертве «заряженную смску» (сообщение в iMessage) и всё, атакующий владеет телефоном. Речь…
#itsec #article
A deep dive into an NSO zero-click iMessage exploit: Remote Code Execution
Подробная техническая статья о том, как именно работает 0-click exploit, позволяющий скомпрометировать устройство без каких-либо действий со стороны пользователя. Опять комбинация out of bounds {write, read} и парсера изображений вкупе с Тьюринговой трясиной одного экзотического формата изображений.
A deep dive into an NSO zero-click iMessage exploit: Remote Code Execution
Подробная техническая статья о том, как именно работает 0-click exploit, позволяющий скомпрометировать устройство без каких-либо действий со стороны пользователя. Опять комбинация out of bounds {write, read} и парсера изображений вкупе с Тьюринговой трясиной одного экзотического формата изображений.
Blogspot
A deep dive into an NSO zero-click iMessage exploit: Remote Code Execution
Posted by Ian Beer & Samuel Groß of Google Project Zero We want to thank Citizen Lab for sharing a sample of the FORCEDENTRY exploit w...
Forwarded from мне не нравится реальность
В свежем Rust 1.58.0 наконец-то можно использовать переменные напрямую при форматировании строк:
let person = get_person();Пока что это работает только с именами, а не произвольными выражениями, но всё равно приятно. Прощайте
// ...
println!("Hello, {person}!"); // captures the local `person`
format!("{name}", name = name);
!Forwarded from мне не нравится реальность
Ещё из плющек:
— теперь
— Теперь правила ансайзинга для дженерик структур немного проще[1]
— В
— реализация
—
[1]: Новые правила позволяют такое:
А полные новые правила такие:
— the tail field depends on at least one type or const parameter not used in any other field
— the target struct can be created from the source by replacing only the parameters only found in the last struct field
— the tail field implements
[2]: Ранее они были отключены из-за того, что их нельзя выполнить в
— теперь
*const T
указатели можно дерефать в константных контекстах— Теперь правила ансайзинга для дженерик структур немного проще[1]
— В
copy{,_nonoverlapping}
опять включили debug_assert
'ы[2]— реализация
Clone
для RSplit<T, P>
больше не требует T: Clone
— Трейт Termiation
теперь реализов для Result<Infallible, E>
, позволяя писать fn main() -> Result<Infallible, ErrorType>
, для програм которые не заканчиваются успешно через выход из main
— Стабилизировали File::options
, замену FileOptions::new
— Стабилизировали {Option,Result}::unwrap_unchecked
— Стабилизировали многие методы Duration
и MaybeUninit
как const fn
— Компилятор теперь будет пытаться применять стабильные методы прежде, чем не стабильные. Это позволит избежать поломок при добавлении в std
методов, пересикающихся по именам с методами из сторонних трейтов.—
rustdoc
теперь показывает методы из всех Deref
реализаций, рекурсивно (а не только из первой)[1]: Новые правила позволяют такое:
struct A<T, U: ?Sized + 'static>(T, B<T, U>);
struct B<T, U: ?Sized>(T, U);
fn main() {
let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
// This previously did not work as the last field of `A` also mentions `T`,
// as only `U` changes this is now allowed thanks to this feature.
let _y: &A<[u32; 1], [u32]> = &x;
}
TL;DR: если последнее поле это структура, которая ансайзиться, то теперь и наружняя структура тоже ансайзиться.А полные новые правила такие:
— the tail field depends on at least one type or const parameter not used in any other field
— the target struct can be created from the source by replacing only the parameters only found in the last struct field
— the tail field implements
Unsize
from source to target[2]: Ранее они были отключены из-за того, что их нельзя выполнить в
const fn
Полный список изменений: RELEASES.md#version-1580-2022-01-13#prog #rust
Хозяйке на заметку
Как известно, если у типа в Rust есть несколько методов от разных трейтов с одними и теми же именами, то попытка вызвать один из них при помощи синтаксиса метода будет прервана компилятором с жалобой на неоднозначность имён, вынуждая прибегнуть к развёрнутому синтаксису вызова (
Хозяйке на заметку
Как известно, если у типа в Rust есть несколько методов от разных трейтов с одними и теми же именами, то попытка вызвать один из них при помощи синтаксиса метода будет прервана компилятором с жалобой на неоднозначность имён, вынуждая прибегнуть к развёрнутому синтаксису вызова (
Trait::method(&value, arg1, arg2)
). Менее известен тот факт, что методы самого типа (inherent methods) перекрывают одноимённые методы трейтов, так что если одному имени отвечают метод типа и сколько угодно методов трейтов, то предпочтение всегда отдаётся методу самого типа и не вызывает неоднозначностей. Этим можно воспользоваться, чтобы иметь возможность в необобщённом контексте вызывать методы трейта, не импортируя сам трейт:trait Trait {
fn method(&mut self, arg: Arg);
}
struct Type {
...
}
impl Trait for Type {
fn method(&mut self, arg: Arg) {
...
}
}
impl Type {
fn method(&mut self, arg: Arg) {
Trait::method(self, arg)
}
}
// где-то в другом месте, где в текущем пространстве имён
// есть Type, но нету Trait:
let mut value = Type::make(...);
value.method(arg);
🔥1
#prog #rust #моё
Допустим, нам нужно сделать на Rust бинарное дерево. Казалось бы, плёвое дело:
Но для начала немного о том, как мы будем задавать высоту. Так как решение на const generics потребует специализации и более продвинутой их обработки и потому абсолютно не реализуемо на стабильной версии, воспользуемся для задания высоты числами Пеано (да, я об этом уже писал):
Кажется, что это изложение довольно легко перекладывается на код: определяем трейт с ассоциированным типом, который уменьшает число на единицу, реализуем его дляnever
С другой стороны, так уж сильно нам его менять не придётся: вместо того, чтобы отображать каждое число на число на единицу меньше, вы воспользуемся структурной индукцией и будем отображать число непосредственно на тип узла:
Как всегда, весь код в гисте. И на этот раз даже больше, чем в посте: добавлены методы для поиска по дереву (с допущением, что дерево является двоичным деревом поиска) и немного более приятная печать.
Оставайтесь на связи. 🤙
Допустим, нам нужно сделать на Rust бинарное дерево. Казалось бы, плёвое дело:
struct TreeNode<T> {
value: T,
left: Option<Box<Self>>,
right: Option<Box<Self>>,
}
struct Tree<T> {
root: Option<TreeNode<T>>,
}
Однако тут у нас по аллокации на каждый узел, от чего у нас страдает локальность данных и, как следствие, эффективность кеша (не говоря уже о стоимости аллокаций в рантайме). С другой стороны, у нас есть возможность делать дерево произвольной (насколько хватит оперативки, конечно же) высоты. А можем ли мы, отказавшись от произвольной высоты и задавая её предел наперёд, хранить вложенные узлы напрямую, а не через указатель? Как оказалось, да!Но для начала немного о том, как мы будем задавать высоту. Так как решение на const generics потребует специализации и более продвинутой их обработки и потому абсолютно не реализуемо на стабильной версии, воспользуемся для задания высоты числами Пеано (да, я об этом уже писал):
struct Z;
struct S<T>(T);
Теперь немного подумаем о том, как это отобразить на древовидную структуру. Каждый узел дерева высотой N + 1 включает в себя узлы высотой N. Узел же дерева с высотой 0 не должен включать в себя данные вообще. Этого можно добиться, сопоставив Z тип с полями ненаселённого типа.Кажется, что это изложение довольно легко перекладывается на код: определяем трейт с ассоциированным типом, который уменьшает число на единицу, реализуем его для
S<T>
с типом T
, а для Z
с типом Infallible
, параметризуем узел высотой Height
и параметризуем вложенные узлы <Height as Decrement>::Output
... К сожалению, это не работает: если определить узел таки образом, rustc не понимает, что рекурсия рано или поздно кончается, и жалуется на бесконечную вложенность типа без индирекции. Кажется, нам нужен другой подход.С другой стороны, так уж сильно нам его менять не придётся: вместо того, чтобы отображать каждое число на число на единицу меньше, вы воспользуемся структурной индукцией и будем отображать число непосредственно на тип узла:
struct Node<T, Next> {
value: T,
left: Next,
right: Next,
}
Тут важно, что поля left
и right
имеют тип Next
, а не Option<Next>
, иначе мы не сможем сделать узел нулевой высоты ненаселённым типом. Собственно, вот как отображение выглядит для Z
:use std::convert::Infallible as Never;
trait Project<T> {
type Projected;
}
impl<T> Project<T> for Z {
type Projected = Node<T, Never>;
}
Итого узел нулевой высоты нельзя сконструировать, как мы и хотели. Лишь немногим сложнее выглядит отображение для S<N>
:impl<T, N> Project<T> for S<N>
where
N: Project<T>,
{
type Projected = Node<T, Option<N::Projected>>;
}
Так как мы не хотим оперировать узлами напрямую (хотя бы потому, что через них затруднительно наложить ограничение на высоту), сделаем обёртку — собственно параметризованное высотой дерево:struct Tree<T, Height: Project<T>> {
repr: Height::Projected,
}
Теперь реализуем парочку вспомогательных методов и попробуем сделать дерево высоты 2 (=S<S<Z>>
):let tree: Tree<i32, S<S<Z>>> = Node {
value: 42,
left: None,
right: Some(Node {
value: 42,
left: None,
right: None
}),
}.into();
Что ж... Оно работает. И даже нормально печатается поле repr
, если добавить #[derive(Debug)]
на Node
. Попробуем теперь поменять тип дерева на дерево с единичной высотой:let tree: Tree<i32, S<Z>> = Node {
...
Компилятор ожидаемо жалуется:error[E0271]: type mismatch resolving <Z as Project<i32>>::Projected == Node<{integer}, Option<_>>Не слишком внятно, но цели статически ограничить высоту дерева мы успешно достигли.
--> src/main.rs:181:7
|
181 | }.into();
| ^^^^ expected enum Option, found enum Infallible
|
= note: expected struct Node<{integer}, Option<_>>
found struct Node<i32, Infallible>
Как всегда, весь код в гисте. И на этот раз даже больше, чем в посте: добавлены методы для поиска по дереву (с допущением, что дерево является двоичным деревом поиска) и немного более приятная печать.
Оставайтесь на связи. 🤙
Telegram
Блог*
#prog #rust #моё #article
Здрасьте. Сегодня поста не будет — но только потому, что я решил написать статью для Хабра. Собственно, вот она.
И напоминаю: если вам это понравилось — поддержите копеечкой автора, я вам благодарен буду: 4274 3200 5402 8520.
Здрасьте. Сегодня поста не будет — но только потому, что я решил написать статью для Хабра. Собственно, вот она.
И напоминаю: если вам это понравилось — поддержите копеечкой автора, я вам благодарен буду: 4274 3200 5402 8520.
Блог*
#prog #rust #моё Допустим, нам нужно сделать на Rust бинарное дерево. Казалось бы, плёвое дело: struct TreeNode<T> { value: T, left: Option<Box<Self>>, right: Option<Box<Self>>, } struct Tree<T> { root: Option<TreeNode<T>>, } Однако тут…
> Антон делает то, что я люблю в программировании больше всего — совершенно беcсмысленный, возведённый в абсолют бред, на который потрачено больше времени, чем стоило бы<...>
Ах, Вафель, ты был абсолютно прав.
Кстати, к него на канале уже 400 человечков! 👀🎉
Ах, Вафель, ты был абсолютно прав.
Кстати, к него на канале уже 400 человечков! 👀🎉
Telegram
Мне не нравится реальность
Антон делает то, что я люблю в программировании больше всего — совершенно беcсмысленный, возведённый в абсолют бред, на который потрачено больше времени, чем стоило бы, но зато... зато красиво!
dereference_pointer_there/1210
dereference_pointer_there/1210
#prog #rust #article
Why is my Rust build so slow? — офигенная статья от Амоса про ускорение компиляции большого проекта на Rust
Why is my Rust build so slow? — офигенная статья от Амоса про ускорение компиляции большого проекта на Rust
fasterthanli.me
Why is my Rust build so slow?
I’ve recently come back to an older project of mine (that powers this website), and as I did some maintenance work: upgrade to newer crates, upgrade to a newer rustc, I noticed that my build was ta...