Не, ну если даже Вафель уехал...
Telegram
Мне не нравится реальность
привет?
Когда Россия вторглась в Украину месяц назад (какой ужас, уже целый месяц прошёл...), я не мог ничего писать, потому что про войну мне сказать было нечего, а про другие темы как-то странно писать... Да и прямо скажем у меня было слишком паршивое…
Когда Россия вторглась в Украину месяц назад (какой ужас, уже целый месяц прошёл...), я не мог ничего писать, потому что про войну мне сказать было нечего, а про другие темы как-то странно писать... Да и прямо скажем у меня было слишком паршивое…
Уже опубликован стандарт C++20 и готовится C++23, а я до сих пор не могу написать переменную с типом "тип возвращаемого значения этой функции"
😁3
#prog #rust #article
Rust's Unsafe Pointer Types Need An Overhaul
Или что не так с сырыми указателями в Rust и что с этим стоило бы сделать
Rust's Unsafe Pointer Types Need An Overhaul
Или что не так с сырыми указателями в Rust и что с этим стоило бы сделать
Faultlore
Rust's Unsafe Pointer Types Need An Overhaul - Faultlore
На долю Толяна David Tolnay приходится порядка 1/14 всех загрузок на crates.io
Twitter
David Tolnay
Extremely many commas in my crates.io dashboard this morning
🔥7👍4
#tips
Функционал Firefox включает в себя возможность делать поисковые запросы прямо из адресной строки. Несколько менее известно, что, напечатав подходящий префикс, можно искать не при помощи Google или Yandex, а при помощи указанной поисковой системы. Например, префикс
Разумеется, это всё настраивается — можно и поменять сам префикс (я вот, например, для поиска по Википедии сделал префикс
Но самое полезное — это префиксы, позволяющие искать по содержимому самого браузера. Это:
Функционал Firefox включает в себя возможность делать поисковые запросы прямо из адресной строки. Несколько менее известно, что, напечатав подходящий префикс, можно искать не при помощи Google или Yandex, а при помощи указанной поисковой системы. Например, префикс
@wikipedia
позволяет искать по, разумеется, Википедии, а префикс @ddg
позволяет искать при помощи DuckDuckGo.Разумеется, это всё настраивается — можно и поменять сам префикс (я вот, например, для поиска по Википедии сделал префикс
w
), и добавить новый поиск. Последнее можно сделать при помощи отдельных аддонов, но можно также просто сделать правый клик по поле ввода поискового запроса на нужном сайте и выбрать в контекстном меню Добавить краткое имя для этого поиска (Add a keyword for this search в английской версии).Но самое полезное — это префиксы, позволяющие искать по содержимому самого браузера. Это:
*
— для поиска по закладкам^
— для поиска по истории%
— для поиска по открытым вкладкам (очень полезно, когда вкладок больше, чем умещается на экран)👍25🤯7🔥3
Achievement get:
Заработать мозоль на ладони, попытавшись открутить очень тугую пробку на бутылке 🙄
Заработать мозоль на ладони, попытавшись открутить очень тугую пробку на бутылке 🙄
👏6❤2🎉2
#prog #video
Quantifying Memory Unsafety and Reactions to It
The fact that C and C++ are not memory safe, leading to vulnerability classes such as use-after-free and buffer-overflow is not new. However, these languages remain in exceptionally wide use, even for new projects. For several years, Fish in a Barrel has been attempting to quantify how common memory-unsafety induced vulnerabilities are in major projects, and researching what tactics are effective at convincing developers to reconsider C and C++.
This talk presents our results: we show the empirical data which leads us to the conclusion that C and C++ are not tenable for modern secure development, including statistics across a large swath of projects. We also present what we've learned about how developers respond to this fact, in the frame of the Five Stages of Grief.
Quantifying Memory Unsafety and Reactions to It
The fact that C and C++ are not memory safe, leading to vulnerability classes such as use-after-free and buffer-overflow is not new. However, these languages remain in exceptionally wide use, even for new projects. For several years, Fish in a Barrel has been attempting to quantify how common memory-unsafety induced vulnerabilities are in major projects, and researching what tactics are effective at convincing developers to reconsider C and C++.
This talk presents our results: we show the empirical data which leads us to the conclusion that C and C++ are not tenable for modern secure development, including statistics across a large swath of projects. We also present what we've learned about how developers respond to this fact, in the frame of the Five Stages of Grief.
👍4💩1
#prog #article (от самого Кармака, кстати)
In-Depth: Static Code Analysis
> It is impossible to do a true control test in software development, but I feel the success that we have had with code analysis has been clear enough that I will say plainly it is irresponsible to not use it.
In-Depth: Static Code Analysis
> It is impossible to do a true control test in software development, but I feel the success that we have had with code analysis has been clear enough that I will say plainly it is irresponsible to not use it.
Gamedeveloper
In-Depth: Static Code Analysis
In this reprinted #altdevblogaday in-depth piece, id Software co-founder and technical director John Carmack shares his experiences with static code analysis and explains why it's irresponsible to not use it.
Блог*
#prog #article Иногда баги очень легко обнаружить. Оригинал Перевод на Хабре
#prog #article
От того же автора: Finding a CPU Design Bug in the Xbox 360, или как инструкция, которая никогда не выполняется, может привести к крашам.
От того же автора: Finding a CPU Design Bug in the Xbox 360, или как инструкция, которая никогда не выполняется, может привести к крашам.
Random ASCII - tech blog of Bruce Dawson
Finding a CPU Design Bug in the Xbox 360
The recent reveal of Meltdown and Spectre reminded me of the time I found a related design bug in the Xbox 360 CPU – a newly added instruction whose mere existence was dangerous. Back in 2005 I was…
❤1👍1
Блог*
Вдобавок ко всему тому, что написано в статье, хочу отметить, что Entry API позволяет просто делать то, что в других языках выглядит зачастую весьма неловко: получить значение по ключу и в случае его отсутствия вставить новое значение, сконструированное при…
#prog #rust #моё
TL;DR: OccupiedEntry::get, OccupiedEntry::into_mut.
Хочу рассказать про один нюанс насчёт этого API, с которым периодически сталкиваются новички. Метод
бежит спрашивать в @rust_beginners_ru открывает доку по
и пишет статью о том, как статически типизированные языки страдают от сложности.
Тем не менее, компилятор тут абсолютно прав. Посмотрим еще раз на сигнатуру
Возникает вопрос: зачем так сделано? Разве нельзя было бы возвращать ссылку, которая бы не заимствовала бы саму
Посмотрим на определение
TL;DR: OccupiedEntry::get, OccupiedEntry::into_mut.
Хочу рассказать про один нюанс насчёт этого API, с которым периодически сталкиваются новички. Метод
entry
возвращает Entry, который буквально либо занятое место, либо свободное:enum Entry<'a, K: 'a, V: 'a> {
Occupied(OccupiedEntry<'a, K, V>),
Vacant(VacantEntry<'a, K, V>),
}
Пусть наш гипотетический новичок хочет таким образом получить доступ к значению из мапы:let val = match map.entry(key) {
Entry::Occupied(e) => ???,
Entry::Vacant(_) => todo!(), // пока нас это не интересует
};
Что же вписать вместо ???
. На это месте наш новичок entry
, доходит до документации по OccupiedEntry
, начинает листать список методов и находит OccupiedEntry::get. "О, это оно!" — восклицает новичок и пишет:let val = match map.entry(key) {
Entry::Occupied(e) => e.get(), // <---- тут
Entry::Vacant(_) => todo!(),
};
, после чего пишет код дальше, запускает и...error[E0597]: `e` does not live long enoughАх, да, тот самый borrow checker. "Но это же абсолютно нормальный код!" — восклицает новичок — "Что этому тупому компилятору не нравится?!". После забрасывает раст, забрасывает программирование, уходит из универа
--> src/lib.rs:5:31
|
4 | let val = match map.entry(0) {
| --- borrow later stored here
5 | Entry::Occupied(e) => e.get(),
| ^^^^^^-
| | |
| | `e` dropped here while still borrowed
| borrowed value does not live long enough
Тем не менее, компилятор тут абсолютно прав. Посмотрим еще раз на сигнатуру
OccupiedEntry::get
:fn get(&self) -> &V
Или, если мы вспомним правила lifetime elision и выпишем времена жизни явно:fn get<'entry>(&'entry self) -> &'entry V
Теперь ещё раз внимательно посмотрим на код:let val = match map.entry(key) {
Entry::Occupied(e) => e.get(), // <---- тут
Entry::Vacant(_) => todo!(),
};
Что тут происходит? e
— это значение типа OccupiedEntry
. Не ссылки на неё! Метод .get()
возвращает ссылку на значение, но для этого он берёт ссылку на e
. Однако после вызова этого метода e
дропается в конце ветки match
— своей лексической области видимости — и таким образом инвалидирует ссылку, возвращённую .get()
. Не удивительно, что компилятор жалуется — в противном случае код давал бы повисшую ссылку!Возникает вопрос: зачем так сделано? Разве нельзя было бы возвращать ссылку, которая бы не заимствовала бы саму
OccupiedEntry
? Но тут возникает вопрос, какое время жизни должна иметь возвращаемая ссылка. Ясное дело, ссылка не может взяться из воздуха, так что произвольным оно быть не может, равно как и 'static
. Тогда какое?Посмотрим на определение
OccupiedEntry
ещё раз:struct OccupiedEntry<'a, K: 'a, V: 'a> {
/* fields omitted */
}
Откуда берётся 'a
? Оно берётся из объемлющей Entry, а оно, в свою очередь, из метода HashMap::entry:fn entry(&mut self, key: K) -> Entry<'_, K, V>
Или же, если расписать времена жизни явно:fn entry<'map>(&'map mut self, key: K) -> Entry<'map, K, V>
То есть OccupiedEntry
параметризованно временем жизни ссылки на мапу. Вопрос: что мешает сделать такой метод?impl<'map, K: 'map, V: 'map> OccupiedEntry<'map, K, V> {
fn get_as_in_map(&self) -> &'map V { ... }
}
Мешает то, что такой метод не мог бы быть безопасным. Рассмотрим такой код в предположении, что такой метод уже написан:let val = match map.entry(key) {
Entry::Occupied(e) => {
// ссылка на значение
let val = e.get_as_in_map();
// убираем значение из мапы
e.remove();
val // и куда теперь указывает ссылка?
}
Entry::Vacant(_) => todo!(),
};
doc.rust-lang.org
OccupiedEntry in std::collections::hash_map - Rust
A view into an occupied entry in a `HashMap`. It is part of the `Entry` enum.
👍7🔥1
Окей, такого метода быть не может. Но неужели мы никак не можем таки получить ссылку на значение с тем же временем жизни, что и ссылка на мапу? На самом деле можем, и этот метод — into_mut:
Первый: можно ли обойтись одним
impl<'map, K: 'map, V: 'map> OccupiedEntry<'map, K, V> {
fn into_mut(self) -> &'map mut V { ... }
}
Обратите внимание, этот метод принимает self
по значению, то есть после его вызова мы уже не можем использовать запись, а значит, и как-то инвалидировать возвращённую ссылку. Возвращаясь к коду нашего новичка, мы можем посоветовать вместо ???
вписать e.into_mut()
:let val = match map.entry(key) {
Entry::Occupied(e) => e.into_mut(),
Entry::Vacant(_) => todo!(),
};
И напоследок ещё пару вопросов.Первый: можно ли обойтись одним
.into_mut()
, без .get()
и .get_mut()
? Нет, поскольку эти методы дают возможность получить доступ к значению и после этого всё же вызвать методы на записи. В качестве примера приведу функцию, которая будет из мапы, хранящей по ключам векторы, доставать из этого вектора последний элемент и удалять этот вектор из мапы, если после этого он стал пустым:fn pop_and_remove_empty(
key: i32,
map: &mut HashMap<i32, Vec<Record>>
) -> Option<Record> {
match map.entry(key) {
Entry::Occupied(mut e) => {
let val = e.get_mut().pop();
if e.get().is_empty() {
e.remove();
}
val
}
Entry::Vacant(_) => None,
}
}
Второй вопрос: обязательно ли было применять .into_mut()
? Строго говорят, нет, поскольку можно было бы написать и без него, воспользовавшись трюком, про который рассказывал Вафель на RustCon2021:let delayed_entry;
let val = match map.entry(key) {
Entry::Occupied(e) => {
delayed_entry = e;
delayed_entry.get()
}
Entry::Vacant(_) => todo!(),
};
В данном случае проблем с повисшими ссылками нету, поскольку delayed_entry
объявлена за пределами match
и потому живёт дольше привязанных внутри значений.doc.rust-lang.org
OccupiedEntry in std::collections::hash_map - Rust
A view into an occupied entry in a `HashMap`. It is part of the `Entry` enum.
👍7🔥1
#music
Задорный чиптюновый трек. И у меня стойкое впечатление, что где-то его уже слышал — не напрямую, так его вариацию.
youtube.com/watch?v=eICgxtddfx0
Задорный чиптюновый трек. И у меня стойкое впечатление, что где-то его уже слышал — не напрямую, так его вариацию.
youtube.com/watch?v=eICgxtddfx0
YouTube
Jakim - Whatever it means
♥
Another one I found a bit difficult to render right audio wise. Hope I did the track justice!
Artist: Jakim
Title: Whatever it means
Check out my channel for more chiptunes. Updating frequently.
Do you think the quality of this upload can be…
Another one I found a bit difficult to render right audio wise. Hope I did the track justice!
Artist: Jakim
Title: Whatever it means
Check out my channel for more chiptunes. Updating frequently.
Do you think the quality of this upload can be…