Обновить
128K+

C++ *

Типизированный язык программирования

247,05
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Корутины C++: как приручить асинхронный I/O

Уровень сложностиСложный
Время на прочтение23 мин
Охват и читатели9.8K

Когда комитет стандартизации проектировал корутины, за кадром остался один неловкий момент: фрейм корутины (coroutine frame) — это динамический объект. Локальные переменные, буферы под чтение, аргументы и состояние автомата с точкой останова co_await должны где-то физически лежать, и по умолчанию компилятор выделяет это пространство из общей кучи через глобальный operator new. В асинхронном GUI, где корутина заводится на каждое нажатие клавиши и на каждое чтение из файла, это означает межпоточные блокировки кучи на каждом шаге с потенциальным переключением контекста — ровно то, от чего корутины обещали избавить.

И это не единственный сюрприз: сам по себе co_await асинхронности не даёт. Учебный awaitable запускает работу только в момент ожидания, и две асинхронные операции подряд на деле не запускаются асинхронно - идут с холостым кругом между ними; чтобы корутины стали по-настоящему асинхронными, механизм запуска операции пришлось отделить от того, что даёт язык. Эти вещи неочевидны, о них почти не пишут, и тем, кто присматривается к корутинам, стоит смотреть на них в первую очередь.

Заглянуть под капот

Откуда берётся сложность

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели24K

Похоже что тема сложности и грязи в играх нашла отклик у читателей Хабра, и @andz даже пообещал поставить тысячу плюсов если бы мог, так что ловите вторую часть, которая должна была быть в части первой, но её там не было.

В основе любого инженерного искусства лежит великая иллюзия контроля над хаосом и открывая пустой файл, мы искренне верим, что в этот раз архитектура точно‑точно останется кристально чистой. Никто в здравом уме не пишет сложный код ради удовольствия (хотя нет, пару человек я все‑таки знаю, но это скорее исключение из правил), и если вы открыли систему частиц и увидели там хардкод для каждой платформы, то это, скорее всего, программисту, писавшему эту систему, выдали число, мало времени и сказали сделать красиво «читобыработало», но читобыработало — не всегда красиво, красиво — не всегда быстро, быстро — не всегда работает.

Число... например, 16 мс или 33 мс или 8 гигабайт, из которых 5 доступны, или «игра должна показать первый интерактивный кадр не позже чем через десять секунд после запуска, иначе сертификацию не пройдем». Как только у свойства системы появляется измеримая цель, простота перестаёт быть бесплатной и превращается в то, чем вы платите.

Читать далее

Частичное применение в C++: владение, время жизни и категории значений

Уровень сложностиСредний
Время на прочтение22 мин
Охват и читатели10K

Носителям прекрасного языка программирования C++ тема частичного применения может показаться скучной. Что примечательного в пяти строчках кода? Но дьявол кроется в деталях: я часто встречал реализации, которые работали не так, как ожидали их авторы. Иногда дело доходило до undefined behavior. Поэтому здесь хочется разобраться прежде всего с владением, временем жизни и категориями значений.

Разобраться в деталях

YOLO‑JSON: Рефлексия + #embed + JSON schema = сверхоптимизированный парсер

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели9.4K

В прошлой статье я представил свою библиотеку для парсинга JSON. Краткое содержание - мы используем новые инструменты стандарта С++26 (в основном, рефлексию) для автоматической генерации оптимизированных парсеров для конкретных JSON, что позволило нам обогнать simdjson в несколько раз.

Здесь мы рассмотрим, как можно генерировать целевые структуры для объектов JSON напрямую из JSON схем при помощи других трюков из стандарта 26.

Читать далее

Выбираем бэкенд в 2026 (PHP, Dart и C++ Drogon)

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели13K

Поехали.

Вообще говоря, я всегда делал бэкенд исключительно на PHP. Я считаю его отличным языком для бэкенда, вернее не только для бэкенда, а отличным языком. Некоторые не любят PHP за малый порог вхождения. Типа через этот малый порог вхождения входит очень много непрограммистов, которые потом пишут говнокод. Но я придерживаюсь мнения, что PHP никак не виноват в этом. Скорее наоборот. На PHP логика просыпается даже у тех, кто кроме говнокода ничего написать не может. Поэтому в любом случае это отличный язык программирования, который каждый год хоронят, но никак похоронить не могут. И в 2026 году он живее всех живых и показывает отличные результаты.

Вторым в списке для сравнения я решил поставить Дарт. Дело в том, что самое узкое место применения Дарта — это как раз-таки применение на серверах. Потому что в мобильной разработке он уже как стандарт, веб, фронтенд мало-мальцевски он тоже подтягивает. Но вот на серверах пока что его используют очень мало. Одна из причин на то, что его мало используют на серверах, — это отсутствие библиотек, таких как, например, есть у PHP. Но, тем не менее, это совсем не значит, а тем более сейчас в эпоху LLM, это совсем не значит, что Дарт негоден на серверах. Как покажет сравнение, он очень-таки годен.

Третий кандидат для сравнения — это C++. Это его фреймворк Drogon, который в каком-то там 2014 или 2015 годах взлетел как самый быстрый фреймворк для серверов на бэкенде по скорости. Если честно, я ни разу не писал бэкенд на C++, поэтому это была первая попытка. Просто хотелось посмотреть, как C++ уничтожит двух других оппонентов со своей 100x производительностью.

Читать далее

Грязные игры

Уровень сложностиПростой
Время на прочтение11 мин
Охват и читатели20K

Вы знаете, что игры бывают очень архитектурно «грязными» внутри? Но это не помешало им продаваться миллионами копий, или быть написаннами одним человеком на фреймворке для браузерок, или на Lua поверх библиотеки для геймджемов, или вообще ребенком в бесплатной версии юнити. При этом мощный кастомный движок с ECS, job‑системой, своим рендером и рефлексией повсюду вы тоже знаете, но игра на нем, скорее всего лежит третий год у вас в беклоге, так и не сыграная даже пару часов.

Попросили меня по старой дружбе, где‑то с полгода назад, помочь с разработкой и выводом игры в Steam. Ребята до этого занимались нефтью, и накопив деньжат, решили, что называется оставить след в индустрии. Если честно, я несколько отвык от такого «детского» кода и простых решений, что меня несколько удивило, хотя и вернуло на грешную землю из объятий ентрепрайза. Но я сразу оговорюсь, что простая архитектура это не оправдание плохого кода, а способ выбрать, где именно вы позволяете себе быть сложным. Бюджет сложности конечен... прежде всего размером вашей натуральной оперативкой, и тратить его надо туда, где игрок это увидит.

Читать далее

Variadic templates в C++. 11 приёмов работы с пакетами параметров

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели6.6K

Привет! Меня зовут Николай, я C++-разработчик в SimbirSoft. В этой статье хочу поделиться практическими приёмами работы с вариативными шаблонами в C++ и разобрать идиомы, которые помогают решать задачи с пакетами параметров — от их перебора и преобразования до использования в более сложных конструкциях.

Мы рассмотрим рекурсию по аргументам и параметрам шаблона, свёртки, работу с лямбда-функциями и requires, мультилямбды, рекурсивные типы через наследование и другие приёмы. На примерах разберём, как современные возможности C++ позволяют сокращать объём шаблонного кода и решать задачи как на этапе компиляции, так и во время выполнения.

Статья будет полезна C++-разработчикам, которые уже знакомы с шаблонами и хотят глубже разобраться в variadic templates и возможностях пакетов параметров. Для комфортного чтения потребуется уверенное владение базовым синтаксисом C++, понимание шаблонов, лямбда-выражений и основных возможностей стандартной библиотеки. Материал ориентирован прежде всего на разработчиков среднего уровня, но будет полезен и тем, кто хочет расширить свой набор практических приёмов современного C++.

Читать далее

WXL: как создавать объекты в 15 раз быстрее

Уровень сложностиСложный
Время на прочтение20 мин
Охват и читатели11K

Обычная системная куча обязана предполагать худшее: что в неё в любой момент постучатся из десятка параллельных потоков. Отсюда неизбежные блокировки, атомарные операции и накладные расходы. Но в GUI-приложениях на WinUI 3 этого сценария просто не бывает — все контролы и элементы разметки создаются и умирают строго в одном-единственном STA-потоке. Зачем же платить за потокобезопасность, которую мы не используем?

В этой статье мы разберем устройство sta_memory_pool — кастомного аллокатора для библиотеки wxl, работающего в 15–16 раз быстрее общей кучи. Вы узнаете, как с помощью инструкции lzcnt вычислить класс размера за один такт, как избавиться от лишних if-проверок на горячем пути с помощью самоперестраивающихся таблиц функций и как заставить линейную аллокацию работать на максимальную отзывчивость приложения при старте.

Заглянуть под капот

Что можно сделать с массивом массивов

Уровень сложностиПростой
Время на прочтение17 мин
Охват и читатели18K

На одном из проектов (4Х историческая стратегия) появилась задача убрать часть логики в потоки, отдав им снапшот игрового состояния, чтобы пока основной поток считает свой тик, остальные (AI, поиск пути, UI и др) могли крутить свою логику, вроде "кто стоит в этой локации" и делать это без блокировок или риска увидеть половину чужой записи. Чтобы реализовать такую систему, надо придумать как получить обратный индекс полка по локации, причем сделать поиск дешевым для потоков, т.е. у потока должен быть свой снапшот состояния некоторой части игрового мира на момент старта апдейта (кадра, тика логики, дня, месяца и т.д)

Общепринятая практика - это сделать данные иммутабельными на время кадра, и построить нужный индекс один раз на старте, а дальше дать читателям возможность работать с ним. И вообщем от ребят, которые делали эту задачу на ревью прилетел вот такой код (выделю тут только основную часть):

std::vector<std::vector<unsigned int>> regiments(location_count);

Такая структура называется jagged array, массив массивов (зачем она и как с ней работать я показывал в книге Game++), или, если вам ближе академическая терминология, CSR (compressed sparse row) немного другая форма записи таких массивов, либо разреженные матрицы. И такие структуры довольно частое явление в играх, если у вас много локаций и вам надо узнать какой лут разложен в каждой локации, какие армии принадлежат каждой области, или какие монстры живут в локации, какие локации входят в область, какие области в регион, или почекать соседей локации на карте, adjacency region, на чем строится весь поиск путей и вся заливка областей в глобальных стратегих;

Читать далее

Я собрала ретрофутуристичную «Виселицу»

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели16K

Оверинжиниринг — это прошлый век. Я работаю в жанре «эпатажный инжиниринг»: у девайса ровно одна функция, а выглядит он как пульт управления инопланетным кораблем. Я обожаю игривую ретрофутуристичную эстетику и в этом проекте выкрутила её на максимум.

Ну и я люблю играть в «Виселицу».

Читать далее

YOLO‑JSON: знание [на этапе компиляции] — сила

Уровень сложностиСредний
Время на прочтение21 мин
Охват и читатели12K

Мы рассмотрим новые возможности рефлекС++ии для проектирования сверхбыстрого JSON. Вашему вниманию представляется библиотека yolo-json, позволяющая интегрировать знания о прибывающих JSON (порядок полей, размеры и т.д.) в удобной манере для достижения высокой скорости парсинга.

Как полусырой код может обойти simdjson? Давайте разберемся.

Читать далее

Как программа для записи ужимается в 40 МБ ОЗУ, пока OBS ест полгига

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели8.2K

На Windows для захвата экрана есть два классических пути: GDI (медленно и печально) и DXGI Desktop Duplication API. HomRec использует второй вариант.

Смысл DXGI Desktop Duplication в том, что видеокарта сама отдаёт вам текстуру рабочего стола — не нужно постранично вычитывать пиксели через GDI. Вызов AcquireNextFrame возвращает GPU‑текстуру с очередным кадром, а если на экране ничего не изменилось — честно говорит «нечего отдавать» (таймаут), и можно просто повторно использовать прошлый кадр вместо лишней работы.

Проблема в том, что эта GPU‑текстура недоступна напрямую из CPU‑памяти — её сначала нужно скопировать в «staging‑текстуру» и замапить. А вот тут прячется первая интересная деталь.

Читать далее

WinUI 3 без XAML: как написать декларативный GUI на чистом C++23, сжав проекцию WinRT в 50 раз

Уровень сложностиСложный
Время на прочтение18 мин
Охват и читатели6.8K

Microsoft рекомендует современный WinUI 3 в качестве официального фундамента для будущих Windows‑приложений. Однако, стандартный стек C++/WinRT + XAML встречает разработчика чудовищным временем компиляции, миксиновым адом вместо нативного наследования, тоннами шаблонной рутины и плохочитаемым кодом.

В этой статье мы разберем архитектуру wxl— тонкой надстройки, которая позволяет описывать GUI на чистом C++23 декларативно (как во Flutter или SwiftUI). Вы узнаете, как сжать заголовочные файлы проекции в 50 раз, сократить время пересборки с полуминуты до 4 секунд, победить накладные расходы QueryInterface с помощью ленивого кэширования интерфейсов на базе STA‑потока и превратить написание нативного GUI в чистое удовольствие.

Заглянуть под капот

Ближайшие события

Компактная кросс‑платформенная open source C++ библиотека для разработки приложений с графическим интерфейсом — Frenchie

Уровень сложностиСредний
Время на прочтение20 мин
Охват и читатели12K

В этой статье я расскажу про возможности компактной кросс‑платформенной библиотеки с открытым исходным кодом для разработки приложений с графическим интерфейсом на языке C++ — Frenchie. Цель материала - познакомить читателей с возможностями библиотеки и сделать сравнение функционала с другими похожими проектами. Если кому-то интересна техническая сторона проекта, то предлагаю заглянуть в исходный код, либо в материалы, описывающие архитектурную и техническую часть.

Читать далее

От Qt5Multimedia до QtAVPlayer

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели8.6K

Во времена, когда Nokia владела Qt, инженеры были отважнее. Они разработали и релизнули QMediaPlayer в Qt5Multimedia для проигрывания медиа файлов на основе подгружаемых плагинов. Архитектура позволяла сначала выпустить API, а реализацию конкретного бекенда добавить позже. Поэтому API уже существовал даже там, где полноценного воспроизведения видео ещё не было.

С учётом того, что публичный API нельзя изменить или удалить в мажорной версии, кто готов проделать такое еще раз?

Этот подход породил интерфейсы, часть функционала которых не так работала или полностью отсутствовала на некоторых платформах.

Читать далее

Упаковщик наносит ответный удар: ZA как машина транспонирования

Уровень сложностиСложный
Время на прочтение9 мин
Охват и читатели6.7K

В этой части мы вернёмся к работе, которую предыдущие главы принимали как готовую: упаковке. Сначала найдём скалярную ловушку в упаковке B, затем используем ZA как машину транспонирования, после этого разберём 128-битный случай для комплексных чисел и правило корректности для общего PACKM_KER. В финале соберём весь цикл одной дугой: от FMOPA до работающей субконфигурации BLIS для Apple SME.

Читать далее

Шаблоны против статической рефлексии в C++: пять операций, две реализации и дедупликация, которая не стоит памяти

Уровень сложностиСложный
Время на прочтение26 мин
Охват и читатели9.1K

Одна и та же операция — дедупликация списка типов — написана двумя способами: на шаблонах и на статической рефлексии из C++26. Обе реализации живут в одном дереве и проверены на идентичность результата, поэтому их можно честно вычесть друг из друга. Получилось так: шаблонная версия съедает 7,9 ГиБ памяти компилятора там, где рефлексивная не съедает ничего измеримого — ±21 МиБ на 32-кратном диапазоне размеров. А по времени обе квадратичны, и рефлексия выигрывает всего пятую часть. Разбираю, откуда берётся такая асимметрия, и заодно пять компиляторных стен, в которые упираешься по дороге, — включая sizeof…, который молча возвращает неверное число.

Читать далее

Эти пчелы делают неправильный с++

Уровень сложностиПростой
Время на прочтение14 мин
Охват и читатели21K

В 2016 году EA закрывает свой последний оплот разработки в Питере, и народ начал разбредаться по разным студиям и командам. Тогда мировой игрострой ещё благосклонно смотрел на обладателей красных паспортов, и несколько моих бывших коллег "со связями" организовали мини-галеру и умудрились получить контракт на поддержку движка для прототипа новой игры Arkane. Причем схема взаимодействия была достаточно мутная, из-за нежелания Остинцев работать напрямую с пост-СНГ конторами, поэтому основной контракт у них был через каких-то корейцев за три рубля, которые делегировали часть работы французкой конторе за рубль, а те наняли каких-то ребят за десять копеек из восточной Европы, ну вы поняли каких:)

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

С этого момента и началось моё знакомство с идеями, которые мы внутри команды прозвали "арканутым C++", и с их реальным применением в разработке игр. Я и раньше сталкивался с жёсткими требованиями к разработке на плюсах на своей доигростростроевской работе, но за шесть лет как-то раздобрел и перестал сильно жестить с оптимизацией, так что знакомство с командой из Остина вызвало стойкое дежавю разработки начала нулевых.

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

Читать далее

QML и CSS не нужны. Использование QStyle (QStyleFactory) для изменения дизайна Qt приложения с выбором для пользователя

Уровень сложностиПростой
Время на прочтение9 мин
Охват и читатели13K

В статье рассказывается о функционале, о котором забыли даже разработчики Qt. Дело в том, что этот функционал даёт уникальные возможности стилизации. В отличие от QML и CSS, использование QStyleFactory позволяет предоставить пользователю широкий выбор QStyle-дизайнов виджетов без затрат времени на настройку QML и CSS. Я много раз видел, как программисты тратят много времени на настройку дизайна через QML и CSS, хотя в Qt 5 и Qt 6 есть база уже готовых дизайнов, которую никто не предоставляет пользователю в качестве выбора. Считаю необходимым рассказать об этом очень удобном и даже ленивом способе настройки дизайна.

Читать далее

WUI три года спустя: C++ интерфейс на Windows, Linux, macOS и в браузере

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели13K

В октябре 2023 года я рассказывал на Хабре о WUI — небольшой UI-библиотеке на C++, которую начал делать для своего приложения. Тогда она работала на Windows и Linux, а macOS оставалась в списке задач.

Теперь у WUI есть бэкенды для macOS и WebAssembly. Можно открыть сайт и пощелкать тот же интерфейс, который собирается в desktop-приложение: кнопки, многострочный ввод, списки, меню, диалоги, разделители. Код контролов и логика демонстрации общие.

Читать далее