1.83K subscribers
3.3K photos
132 videos
15 files
3.58K links
Блог со звёздочкой.

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

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Так как хештег #mood себя замарал [1], введу новый хештег тупо для музыки, без какой-либо инфы. И назову его #music. Да.

А чтобы это не был пост ради поста — держите музон.

[1]: @dereference_pointer_there/572
Forwarded from You Had No Job
Указом царя крепостные были переименованы в стажёров
Когда накосячил в ансейфе на #rust
Сегодня снился говнокод на плюсах. К чему бы это?
Forwarded from Deleted Account
В джаве все есть для нормальной жизни
Forwarded from Deleted Account
Кроме языка программирования
Forwarded from Tester of QA
Новое слово вам в словарик: "дыработка".
Что-то на канале в последнее время один сплошной шитпостинг. Надо уже что-то своё постить
#prog #rust

Поздравляю Вафлю! Лучшая кошкодевочка, однозначно.
Forwarded from мне не нравится реальность (вафель 🧇🍓)
Привет девочки!!

Мой PR в std (alloc) добавляющий Vec::extend_from_within наконец-то смерджили (tracking issue)!

tl;dr:
— Этот метод был предложен в RFC pr #2714
— Этот метод используется в разных крейтах и раньше его неправильные реализации приводили к UB
— Метод позволяет скопировать (склонировать) данные из вектора и добавить их в его же конец

let​ ​mut​ vec ​=​ ​vec!​[​0​, ​1​, ​2​, ​3​, ​4​];

vec.​extend_from_within​(​2​..);
​assert_eq!​(vec, [​0​, ​1​, ​2​, ​3​, ​4​, ​2​, ​3​, ​4​]);
#prog #c #cpp #article

C-Reduce (GitHub) — C-Reduce is a tool that takes a large C, C++, or OpenCL file that has a property of interest (such as triggering a compiler bug) and automatically produces a much smaller C/C++ file that has the same property. It is intended for use by people who discover and report bugs in compilers and other tools that process source code.

В силу того, что принципиальный алгоритм для сокращения тестов, вопреки названию, не привязан к конкретному языку, на практике с успехом применяется и для сокращения тест-кейсов на других ЯП.

Также имеется статья в двух частях (первая, вторая) от создателя о дизайне C-Reduce (в частности, о том, как там можно применить многозадачность) и о том, как он работает на практике.
Блог*
#prog #c #cpp #article C-Reduce (GitHub) — C-Reduce is a tool that takes a large C, C++, or OpenCL file that has a property of interest (such as triggering a compiler bug) and automatically produces a much smaller C/C++ file that has the same property. It…
#prog #article

Данная статья рассказывает о фреймворке Perses для сокращения тестовых программ, который оперирует над вариантом контекстно-свободных грамматик, и за счёт этого:
1) Генерирует лишь синтаксически валидные программы, за счёт чего не теряет время на отбрасывание заведомо некорректных программ.
2) Позволяет проводить более продвинутые изменения кода, чем те, на которые способны более простые (Hierarchical) Delta Debugging (они также определяются в самой статье, так что не переживайте, если этот термин вам ни о чём не говорит).
3) Не привязан к конкретному языку (авторы смогли успешно применить его как для программ на C, так и для программ на Java).

Разумеется, помимо прочих вариантов авторы сравнили свой фреймворк и с C-Reduce. В смысле эффективности сжатия тестовых кейсов C-Reduce работает более эффективно за счёт большего количества C/C++-специфичных эвристик, но Perses тратит меньше времени на минимизацию и делает меньше тестовых запусков. Как итог, авторы предлагают на практике сначала запускать свой фреймворк, а потом уже допиливать при помощи C-Reduce
#prog #rust #моё

В Go есть такая фича, как iota. Это магический идентификатор, который можно использовать в блоке констант и который автоматически заменяется на порядковый номер в блоке констант. Наглядный пример:

package main

import (
"fmt"
)

const (
a = 0
b = 1 << iota

_
// Oh hi Mark
c
)

const (
d = iota
)

func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}

Вывод:

0
2
8
0

Данный пример демонстрирует, что:

* iota автоматически становится числом, соответствующим номеру непустой строки без комментариев
* выражение для константы можно опустить, в этом случае оно становится (символически) идентичным последнему непустому выражению
* константу можно явно пропустить, в этом случае iota всё равно будет инкрементирована
* счётчик iota действует только в рамках одного блока деклараций констант, в следующем блоке он сбрасывается

На практике эта фича может быть полезна для определения битовых флагов:

const (
FLAG_A = 1 << iota
FLAG_B
FLAG_C
FLAG_D
)

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

Сегодня я сделаю на Rust макрос, который, насколько возможно, воспроизводит это поведение.

Прежде чем я приступлю к реализации, хочу отметить, что добиться в полной мере той же эргономики, что и на Go, несколько проблематично, поскольку в Rust декларативные макросы (а я собираюсь ограничиться именно ими) имеют гигиену и потому не могут генерировать новые идентификаторы, доступные извне макроса, а могут лишь использовать те, что уже имеются. Это можно решить, вручную выискивая iota в выражениях — это путь сильных, точнее, путь Толяна, поскольку в этом случае требуется вручную делать рекурсивный спуск внутрь выражений со скобками. Я же пойду по пути наименьшего сопротивления и обязую пользователя макроса предоставить идентификатор, который будет использован в качестве iota.

Давайте немного подумаем о том, как же решить задачу инкрементации. В силу того, что декларативные макросы можно считать некоей убогой разновидностью функционального программирования, воспользуемся подходами из ФП. Вместо того, чтобы сразу сгенерировать всю числовую последовательность, мы будем рекурсивно обрабатывать список деклараций, поддерживая текущее значение iota, и после генерации очередной константы вызывать макрос на остатке входа, передав инкрементированное значение iota.

Ещё один вопрос — как поддержать возможность опустить выражение для константы. Получается, что, помимо текущего значения iota, нам также нужно хранить выражение для константы. Оно передаётся дальше при рекурсивном вызове, при этом оно либо замещается текущим, если оно есть, либо используется и передаётся дальше без изменений.

Разумеется, рекурсию нужно с чего-то начать. Базой индукции послужит инициализация iota нулевым значением, а выражение для константы можно инициализировать самой iota:

macro_rules! iota_consts {
(
$iota:ident: $($tt:tt)*
//^ ^^весь остальной вход
//\- идентификатор для iota
) => {
iota_consts!(
$iota(0, $iota): $($tt)*
);
};
...

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

$(#[$attr:meta])*
$vis:vis
const $name:ident : $ty:ty