Почему промты для C++ и Rust — это отдельная дисциплина
Системное программирование не прощает абстрактных формулировок. Когда вы просите LLM «оптимизировать код», вы получаете generic-ответ. Когда вы просите «убери лишнюю аллокацию в hot path и покажи, где UB по restrict-квалификаторам» — ответ становится инженерным. Разница — в контексте: модель должна понимать модель памяти, правила aliasing и особенности таргета (x86-64, ARM Cortex-M, RISC-V).
Эта подборка — 12 промтов, проверенных на реальных задачах: от отладки use-after-free в C++ до написания unsafe-обёрток в Rust и кросс-компиляции под bare-metal. Каждый промт — это не «вопрос», а структурированный запрос с ролью, ограничениями и форматом вывода.
Базовый уровень: память, указатели, сборка
1. Диагностика UB и работы с указателями в C++
Задача: найти неопределённое поведение до того, как оно проявится в продакшене.
Промт:
Ты — эксперт по C++ с опытом работы в стандартном комитете. Проанализируй код ниже на предмет UB по ISO C++20 [N4861].
Для каждой проблемы укажи:
1. Строку и правило (например, [expr.add]/4).
2. Почему это UB, а не unspecified behavior.
3. Минимальный фикс без смены архитектуры.
Не предлагай переписать на Rust. Вывод — таблица: строка
| правило | фикс.
Результат: модель находит выход за границы массива, нарушение strict aliasing и порядок разрушения объектов — со ссылками на параграфы стандарта.
2. Работа с unsafe в Rust: аудит и обёртки
Задача: обернуть C-библиотеку безопасным API.
Промт:
Сгенерируй безопасную Rust-обёртку над C-функцией ниже. Требования:
- Публичный API не содержит unsafe.
- Инварианты (длина буфера, lifetime) проверяются в конструкторе.
- Используй std::marker::PhantomData где нужно.
- Покажи, какие условия делает безопасными каждый unsafe-блок (комментарий // SAFETY:).
Результат: вы получаете struct с приватными полями и публичными методами, где каждый unsafe документирован — это соответствует практике из Rustonomicon.
3. Понимание ассемблера под конкретный таргет
Промт:
Скомпилируй мысленно этот C-код для ARM Cortex-M4 (thumbv7em-none-eabihf) с -O2. Объясни:
- Какие регистры задействованы.
- Где компилятор вставил барьеры памяти.
- Почему цикл не развёрнут.
Затем предложи вариант, который уменьшит размер кода без потери скорости.
Продвинутый уровень: многопоточность и производительность
4. Поиск data race и deadlock
Промт:
Проверь код на гонки данных и дедлоки. Используй модель памяти C++ [atomics.order].
Для каждой проблемы: минимальный interleaving, который её вызывает.
Предложи фикс с std::atomic и memory_order_acquire/release, объясни выбор.
5. Бенчмарки и профилирование
Промт:
Составь Google Benchmark для функции ниже. Учти:
- Warmup и DoNotOptimize.
- Разные размеры входов (1KB, 1MB, 100MB).
- Сравнение с baseline.
Выведи таблицу ожидаемых метрик (ns/op, cycles/byte) и объясни, что покажет perf stat.
6. Оптимизация аллокаций в hot path
Промт:
Перепиши код так, чтобы убрать malloc/free из горячего цикла.
Варианты: пул объектов, arena allocator, std::pmr.
Для каждого — trade-off по latency и памяти. Покажи микробенчмарк.
7. Многопоточность в Rust: Send/Sync и каналы
Промт:
Объясни, почему этот тип не реализует Send. Покажи минимальный пример,
где компилятор откажет. Затем предложи дизайн с crossbeam-channel,
сохранив инварианты безопасности.
Экспертный уровень: FFI, embedded, кросс-компиляция
8. FFI между C++ и Rust без утечек
Задача: вызывать Rust из C++ и наоборот.
Промт:
Сгенерируй cxx-мост между C++ классом Widget и Rust структурой.
Требования: без копирования строк, обработка исключений C++ через Result,
корректная деструкция через UniquePtr. Покажи build.rs и CMake.
Результат: рабочий пример с cxx::bridge, где std::unique_ptr и Box не конфликтуют.
9. Embedded: no_std и прерывания
Промт:
Напиши драйвер UART для STM32F4 на Rust no_std с обработкой прерываний
через cortex-m-rt. Используй volatile и критическую секцию.
Объясни, почему обычный static mut — плохая идея.
10. Кросс-компиляция и reproducible builds
Промт:
Настрой кросс-компиляцию C++/Rust проекта под aarch64-linux-gnu и
thumbv7em-none-eabihf. Покажи CMake toolchain и .cargo/config.toml.
Добавь флаги для reproducible builds (-ffile-prefix-map, --remap-path-prefix).
11. Высоконагруженный сервис: backpressure и zero-copy
Промт:
Спроектируй сервис на Rust с tokio, обрабатывающий 100k RPS.
Требования: zero-copy парсинг через bytes::Bytes, backpressure через bounded channel,
метрики через metrics-rs. Покажи структуру модулей и ключевые типы.
12. Безопасность памяти: аудит зависимостей
Промт:
Проверь Cargo.toml на известные уязвимости (RUSTSEC). Для каждого crate:
альтернатива, статус maintenance, наличие unsafe. Оформи таблицей
с приоритетами и планом миграции.
Как использовать эти промты эффективно
Три правила из практики: во-первых, всегда указывайте таргет и версию стандарта — LLM без этого даёт усреднённый ответ. Во-вторых, просите формат вывода (таблица, diff, чек-лист) — это снижает галлюцинации. В-третьих, проверяйте ссылки на стандарты: ISO C++ [N4861], Rust Reference, ARM ARM — модель может ошибаться в номерах параграфов.
Полезные источники: cppreference.com, doc.rust-lang.org/nomicon, RUSTSEC Advisory Database, а также RFC 2119 для формулировки требований в промтах. Если вы только входите в системное программирование, начните с промтов 1–3, затем переходите к FFI и embedded — там отдача максимальная.
Сохраните эту подборку как шаблон и адаптируйте под свой стек: чем точнее контекст, тем меньше времени на ревью сгенерированного кода.
Комментарии