Библиотека C/C++ разработчика | cpp, boost, qt
19.1K subscribers
2.09K photos
67 videos
16 files
4.41K links
Все самое полезное для плюсовика и сишника в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/d6cd2932

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5bac324c8ba6dcaa1ad17

#WXSSA
Download Telegram
🍬 Closure size и SBO: когда лямбда уходит в куч

Размер объекта-замыкания напрямую влияет на то, выделяется ли память в куче при хранении в std::function. Понимание Small Buffer Optimization критично для low-latency кода.

⚡️ std::function содержит внутренний буфер (обычно 16–32 байта в зависимости от реализации). Если closure влезает — heap allocation не происходит:

// sizeof closure = sizeof(int) = 4 байта → SBO
auto f1 = [x = 42]() { return x; };
std::function<int()> sf1 = f1; // нет heap allocation

// sizeof closure = 3 * sizeof(string) → возможно > SBO
std::string s1, s2, s3;
auto f2 = [s1, s2, s3]() { return s1 + s2 + s3; };
std::function<int()> sf2 = f2; // возможно heap allocation


🔍 Практическое правило: захватываешь больше 3-х примитивных значений — жди heap allocation. std::string, вектор, любой объект с указателем внутри — почти гарантия.

⚠️ Решения для latency-sensitive кода:

• std::move_only_function (C++23) — меньше overhead, нет копирования
• Ручной std::aligned_storage + placement new

❗️ SBO — деталь реализации стандартной библиотеки, не гарантированная стандартом. Для критичного кода измеряй, не предполагай. Конкретный порог зависит от libstdc++/libc++/MSVC STL.

📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#под_капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
👍65
👻 std::span в C++26: то, что должно было быть с самого начала

«Почему нельзя просто передать {1, 2, 3} в функцию?!» — знакомое чувство, когда компилятор смотрит на тебя с осуждением за какой-то список чисел.


💡 std::span появился в C++20 и сразу стал удобным инструментом — но с заметными шероховатостями. В C++26 их наконец-то зашлифовали.

Что изменилось:

span<const T> теперь понимает {1, 2, 3} без магии двойных скобок — просто работает
• добавили at() с проверкой границ, как у всех нормальных контейнеров. Да, его не было. Да, это странно
• CTAD стал умнее: если размер известен на этапе компиляции — он и выводится как статический, а не теряется в dynamic_extent

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

👉 Статья

📍Навигация:
ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#буст
4👍2
🍿 Почему локальные переменные «бесплатны» — и что на самом деле происходит при их создании?

Большинство разработчиков знают, что локальные переменные живут на стеке. Но мало кто задумывается: что значит «выделить память на стеке»? Спойлер — никакого malloc там нет.

🔍 Механизм

Стек — это непрерывный блок памяти, закреплённый за потоком при его запуске (обычно 1–8 МБ). Управление им сводится к одному регистру — rsp (stack pointer). При входе в функцию компилятор заранее вычисляет суммарный размер всех локальных переменных и генерирует одну инструкцию:

sub rsp, 48   ; "выделить" место под все локалы сразу
; 48 - смещение в байтах, на которое
; нужно сдвинуть указатель, чтобы
; выделить память под переменные


Никакого поиска свободного блока. Никакого обращения к ОС. Одна арифметическая операция над регистром.


⚡️ При выходе из функции

add rsp, 48   ; "освободить" — снова одна инструкция


Данные никуда не деваются физически — они просто становятся «за пределами» стека. Следующий вызов функции затрёт их своими данными.


❗️ Почему это важно

Аллокация на стеке — это O(1) по времени и нулевые накладные расходы на освобождение. Именно поэтому int x = 5; внутри функции принципиально дешевле new int(5) — разница не в синтаксисе, а в том, какой механизм памяти задействован.

✏️ Если видишь узкое место с частыми мелкими аллокациями — сначала спроси: можно ли это положить на стек?


📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#под_капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71🔥1
Почитали тут свежий отчёт по рынку ИИ-ускорителей в РФ: оказывается, 54% компаний тормозят внедрение ИИ исключительно из-за конских цен на инфраструктуру.

Ну, то есть написать пет-проект с вызовом API это задача на вечер, а вот запустить агента в продакшн так, чтобы он не сжёг бюджет отдела за неделю — суровая инженерия.

По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать time-travel дебаг в LangGraph и уметь роутить запросы на лету. Всё это мы учли в обновлённом курсе по разработке AI-агентов, где акцент сделан именно на AgentOps и жёсткий контроль ресурсов.

Также в программе:

— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу MCP;
— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).

Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.

Прямо сейчас можно урвать курс с увесистой скидкой (49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек), но стоит поторопиться — на потоке осталось всего 5 мест.

👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде
😁1
📰 Свеженькое из мира C++

Подготовили подборку самых интересных материалов за неделю о разных аспектах программирования и интересных проектах в мире C++.

😎 Интересное:

Современный C++ для встраиваемых систем — подробный разбор того, как использовать современный C++ в embedded-системах
std::mem_fn vs лямбда — удобная альтернатива лямбдам для оборачивания методов
C++23 и дальше — альтернатива исключениям для обработки ошибок в функциональном стиле
Почему опытным PM, PO и руководителям тоже нужен менторинг — разбор, нужно ли дальнейшее развитие если ты уже PM
Closure size и SBO: когда лямбда уходит в куч — ответ почему лямбда может оказаться в куче
std::span — обёртка над массивами в C++26 стала ещё удобнее и появилось много полезных особенностей
Почему локальные переменные «бесплатны» — описание почему локальные дешевле выделения памяти в куче

🔹📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#свежак
3😁2🥰1
Какой механизм C++23 позволяет избежать лишних копирований при передаче объектов в функцию, не нарушая семантику значений?
Anonymous Quiz
22%
Явное перемещение через std::move
15%
Передача через const lvalue-ссылку
28%
Универсальная ссылка через T&&
17%
Deducing this
18%
Copy elision через NRVO
🌚9👍1😁1😢1👾1
🦴 Сколько стоит LOG_DEBUG()?

Автор статьи провёл benchmark четырёх популярных C++ библиотек логирования и выяснил, сколько на самом деле стоит один вызов LOG_INFO().

Ключевые моменты статьи:

• разница в производительности между библиотеками достигает почти двух порядков
• даже отключённый лог имеет ненулевой overhead — библиотека всё равно проверяет уровень и готовит аргументы
• выбор API форматирования бьёт по скорости: iostream в 4–5 раз медленнее C-style printf


Основной фокус — null-benchmark: измерение стоимости самого вызова логирования, когда вывод отключён. Именно здесь разрыв между библиотеками оказывается максимальным.

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


🔹📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#свежак
😁1
🩹 promise_type::operator new — кастомная аллокация фрейма

Корутина выделяет фрейм через ::operator new. Но этот вызов можно перехватить и направить в любой аллокатор — арену, пул, стек. Механизм называется coroutine allocator customization.


👁 Как это работает

Когда компилятор генерирует код запуска корутины, он ищет operator new в двух местах по порядку: сначала в типе promise_type — если есть, использует его; затем глобальный ::operator new.

struct MyPromise {
static void* operator new(std::size_t size) {
return my_pool.allocate(size);
}
static void operator delete(void* ptr, std::size_t size) {
my_pool.deallocate(ptr, size);
}
};



⚡️ Параметры аргументов корутины

Стандарт позволяет передать аргументы самой корутины в operator new. Компилятор сначала пробует сигнатуру с аргументами:

static void* operator new(std::size_t sz, Allocator& alloc, auto&&...) {
return alloc.allocate(sz);
}


Это мощно: можно пробросить аллокатор как первый параметр корутины и использовать его для фрейма — без глобального состояния.


‼️ Heap Elision и operator new

Если компилятор применяет heap elision и вообще убирает аллокацию — ваш кастомный operator new не вызовется. Это нормально. Но если вы используете operator new для отладки размеров, убедитесь что оптимизация отключена (-O0 или [[clang::noinline]] на корутину).


Применение

Кастомный аллокатор в корутинах даёт: lock-free аллокацию, аллокацию с арены (без освобождения по одному), размещение на стеке вызывающего. Последнее — буквально O(1) без heap, если время жизни гарантировано.


📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#под_капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
6❤‍🔥3👍2😁1😢1
👑 IntelliJ IDEA: продвинутый дебаг

Представь, что есть цикл на 10 000 элементов, и баг воспроизводится только на одном конкретном объекте. Без Conditional Breakpoints придется жать F8 вручную сотни раз. А с ними дебаггер сам остановится в нужный момент.

🔹 Как включить


Кликни правой кнопкой на кружок брейкпоинта → появится поле Condition. Введите любое булево Java-выражение. Всё, дебаггер будет останавливаться только когда оно true.

🔹 Примеры из реальной жизни

▪️ Фильтрация по ID
user.getId() == 42

Останавливаемся только на конкретном пользователе — удобно при обработке списка сущностей из БД.

▪️ Фильтрация по содержимому строки
request.getUrl().contains("/admin")

Отлавливаем только определённые HTTP-запросы в фильтре или интерцепторе.

▪️ Ловим NPE до того, как он случился
order.getItems() == null

Останавливаемся именно тогда, когда данные уже сломаны, а не после падения.

▪️ Условие по индексу в цикле
i == 999

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

🔹 Продвинутые трюки

— Log message вместо остановки. Если не хотите прерывать выполнение, а просто логировать — в том же окне брейкпоинта включите "Evaluate and log" и введите выражение.

— Pass count. Чуть ниже в настройках брейкпоинта есть поле "Pass count" — брейкпоинт сработает только на N-м попадании.

— Disable until hit. Можно настроить цепочку: один брейкпоинт активирует другой. В настройках есть "Disable until breakpoint is hit" — указываете другой брейкпоинт, и текущий начнёт работать только после срабатывания того.

⚠️ Condition вычисляется на каждом попадании в брейкпоинт — это вызов на стороне JVM. В горячих местах (tight loop, высоконагруженный метод) это может заметно тормозить приложение.

══════ Навигация ══════
ВакансииЗадачиСобесы

🐸 Библиотека джависта

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
💡 sentinel_t — зачем ranges придумали конец диапазона как отдельный тип

В классических итераторах begin и end — один тип. В ranges конец диапазона может быть совершенно другим типом. Это ломает интуицию, но открывает возможности.


🔍 Проблема однотипных итераторов

std::string::iterator для begin и end — одно и то же. Чтобы проверить конец, нужно держать два объекта одного размера и сравнивать их. Для C-строк это расточительно: \0 в памяти уже есть, но стандартный end — это полноценный указатель.


⚡️ Sentinel как концепт

В ranges введён концепт sentinel_for<S, I>: тип S является sentinel для итератора I, если их можно сравнивать оператором ==, даже если S != I.

// Sentinel для null-terminated строки
struct null_sentinel {
bool operator==(const char* p) const { return *p == '\0'; }
};

// Теперь можно:
auto r = subrange(ptr, null_sentinel{});


💡 unreachable_sentinel

Специальный std::unreachable_sentinel_t всегда возвращает false при сравнении — это сигнал компилятору, что конец никогда не достигается в данной ветке. Используется в take_view и counted_iterator, чтобы избежать лишних проверок в горячих циклах.

auto v = std::views::counted(ptr, n); 
// end() имеет тип unreachable_sentinel_t
// компилятор оптимизирует проверку конца


⚠️ Именно из-за разнотипных sentinel std::ranges::distance работает за O(n) для forward-итераторов — он вынужден идти до sentinel, не зная расстояния заранее.

Sentinel — это обобщение понятия «конец», а не просто переименование end().


📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#под_капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7👾1
😎 Топ-вакансий для C++ разработчиков за неделю

Senior Embedded Software Engineer — от 350 000 ₽ Удалёнка

Middle+/Senior C++ Developer —от 2500 и до 3500 $ Удалёнка

C/C++ developer — от 200000 ₽ Удалёнка/гибрид (Москва)

✍️ Еще больше топовых вакансий — в нашем канале C++ jobs

📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#буст
😁2
🚀 Вышел Qt 6.11

23 марта Qt Company выпустила Qt 6.11 — промежуточный релиз стабильной ветки Qt 6. Полгода публичной поддержки + ещё полгода для коммерческих пользователей.

🦴 Главное в релизе:

🎨 Qt Canvas Painter — новый модуль для аппаратно ускоренной 2D-отрисовки через RHI (OpenGL, Vulkan, Metal, Direct3D). В тестах обгоняет QPainter+OpenGL: в 2× на ноутбуке, в 5× на бюджетном Android-планшете, в 10× на флагманском Samsung Galaxy Tab S8
🌐 Qt WebEngine — поддержка расширений Chromium
🔊 PipeWire — встроенный аудиобэкенд
🎮 Qt Quick 3D — добавлены SSGI и SSR (реалистичное освещение и отражения в реальном времени), улучшено сглаживание движущихся объектов
📊 Qt Graphs — новый тип CustomSeries для произвольных графиков, поддержка нескольких осей в 3D-графиках, пример Wind Turbine Dashboard
⚡️ Qt TaskTree (экспериментальный) — декларативный подход к асинхронным задачам на C++.
🔗 Qt OpenAPI — генерация HTTP-клиентского кода из YAML-спецификации OpenAPI
📱 Android 16 + поддержка Google Play Feature Delivery для разбивки приложений на пакеты
🖼 SVG/Lottie — поддержка морфинг-анимации, масок и символов SVG, стабилизация Qt Quick VectorImage

✏️ Подробнее


📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#свежак
🔥6👍21🙏1
😱 Если ваш продукт не умеет отдавать данные в формате, понятном AI-агенту, то вас просто не существует

Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности.

Как адаптировать продукт и не исчезнуть из выдачи:

— интегрировать MCP и A2A-взаимодействие, чтобы агенты могли вас читать;
— научиться контролировать стоимость (лимиты, кэш, роутинг между моделями);
— настроить AgentOps: трейсинг, логирование и отлов регрессий.

Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях.

Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше.

Зафиксировать цену и начать деплоить агентов без слива бюджета 👈
🥱6😁5🔥1
⚡️ Бесплатный генератор CMakeLists.txt

QuickCoderHub выкатил бесплатный браузерный генератор CMakeLists.txt для C++ проектов — никакой установки, работает полностью в браузере.


❗️ Ключевые моменты инструмента:

• визуальная настройка и автогенерация CMakeLists.txt прямо в браузере
• нулевые зависимости — не нужно ничего устанавливать на машину
• мгновенный результат без ручного написания конфигурационных файлов

Основной фокус — убрать рутину настройки системы сборки и дать разработчику готовый CMakeLists.txt под его проект за секунды.

Удобно при старте нового проекта, на собеседованиях, или когда нужно быстро поднять сборку без погружения в документацию CMake.

🍪 Генератор

📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13💯1