Обновить
64K+

Компиляторы *

Из исходного кода в машинный

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

В С неопределённое поведение повсюду

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

Если бы Кардинал Ришелье был программистом, он бы сказал: «Дайте мне шесть строк кода, написанных рукой самого профессионального C-программиста в мире, и я найду в них лазейку для вызова неопределённого поведения.

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

C++ послужил нам сполна, но на дворе 2026 год, и современная рабочая среда явно отличается от среды 1985 (C++) или 1972 (С).

И я далеко не первый, кто об этом заговорил. Помню ещё с десять лет назад читал статью какого-то известного человека, в которой он утверждал, что использование C++ вполне обоснованно можно подвести под нарушение закона Сарбейнза-Оксли (SOX). И хотя с остальной его критикой я не был согласен (как и с тем, что он путал «its» и «it’s»), конкретно с этим пунктом я никогда не спорил.

Мало того, со временем я всё больше убеждался в его истинности. На деле в С для возникновения неопределённого поведения (undefined behaviour, UB) есть гораздо больше возможных причин, чем вы могли предполагать.

Все знают, что двойное освобождение памяти, её использование после освобождения, выход за границы объекта (например, массива) и чтение неинициализированной памяти — это UB. Как ни крути, но в контексте работы с памятью C и C++ безопасными не назовёшь. Тем не менее даже эти ошибки продолжают совершаться повсеместно раз за разом.

Читать далее

Новости

AsmX с движком Raptor: Архитектура абсолютного контроля

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

Raptor Engine: Как 30 000 строк кода на TypeScript вдохнули жизнь в компилятор AsmX

Можно ли объединить абсолютный контроль низкоуровневого ассемблера x86-64 с изяществом ООП, шаблонов и безопасных абстракций в духе C++? Разбираем масштабное обновление отечественного компилятора AsmX. Под капотом — честные 30 тысяч строк хардкорной архитектуры: от прямого доступа к аппаратной SIB-адресации CPU и хитрых махинаций с регистрами при вызове знаковых movsx/imul/idiv, до разбора анатомии новой стандартной библиотеки (std::optional и std::pair), работающей по принципу Zero-Cost Abstractions. Узнайте, как мономорфизация AST-деревьев и System V ABI позволяют выжимать максимум из кремния без единого байта накладных расходов.

Читать далее

Твой код на Rust компилируется, проходит тесты и является UB. Ты просто об этом не знаешь

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

Если взять случайный крейт с crates.io и поставить его под Miri, шанс увидеть undefined behavior где-то в зависимостях стремится к единице. Разбираемся, почему: pointer provenance, Stacked Borrows, Tree Borrows и почему noalias в LLVM выключали три раза.

Читать далее

C++: Как мы докатились до Hello World в 2 МБ

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

Казалось бы, современный С++ дает столько возможностей… Давайте попробуем препарировать всю эту необъятную мощь, начав с первого шага в любом языке программирования — «Hello World».

Как реализации компиляторов встречают новичка, впервые написавшему свои первые строчки кода?

Узнать, как же мы до такого докатились

Опыт написания компилятора вручную: Часть 2

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

Компилятор и главный репозиторий: GitHub

Здесь я напишу о своём личном проекте — компиляторе к C-подобному языку. Я не являюсь профессиональным разработчиком, изучал эту тему почти самостоятельно и не читал никакие книги по написанию компиляторов (но читал по операционным системам).

Читать далее

Как Rust обманывает процессор. Часть 2: niche сквозь крейты, dropck, Pin и провенанс указателей

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

Как Rust обманывает процессор. Часть 2: niche сквозь крейты, dropck, Pin и провенанс указателей

В первой части мы обсуждали niche-оптимизацию, drop flags, MIR, Stacked Borrows и async-стейт-машины. В комментариях справедливо заметили (спасибо, Mingun): про niche рассказано в простой форме - Option<&T> и NonZeroU8.

А что происходит, когда enum живёт в одном крейте, оборачивается в newtype в другом, и оба варианта внешнего enum хранят один и тот же внутренний? У такого внешнего типа всего четыре состояния, байта должно хватить. Хватит ли? Зависит от того, как rustc считает layout. Об этом и поговорим.

Во второй части идём глубже: niche сквозь границы крейтов, variance, Pin и самоссылающиеся футуры, dropck с #[may_dangle], Tree Borrows вместо Stacked Borrows и strict provenance. Без этого половина unsafe-кода в экосистеме держится на честном слове.

Читать далее

Что именно я понимаю под промежуточным представлением (IR) компилятора

Время на прочтение12 мин
Охват и читатели10K

Я много думал о том, как проектируются промежуточные представления (IR) для компилятора. В этом посте я поделюсь с вами некоторыми идеями, к которым я пришёл, и поясню, почему считаю их важными.

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

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

Читать далее

Часть I. Конечные автоматы. Универсальная машина Тьюринга. Интерпретатор Brainfuck

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

▒▒▒▒▒▒▒▒▒█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
▒▒▒▒▒▒▒█░▒▒▒▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒░█
▒▒▒▒▒▒▒█░▒▒▓▒▒▒▒▒▒▒▒▒▄▄▒▓▒▒░█░▄▄
▒▒▄▀▀▄▄█░▒▒▒▒▒▒▓▒▒▒▒█░░▀▄▄▄▄▄▀░░█
▒▒█░░░░█░▒▒▒▒▒▒▒▒▒▒▒█░░░░░░░░░░░█
▒▒▒▀▀▄▄█░▒▒▒▒▓▒▒▒▓▒█░░░█▒░░░░█▒░░█
▒▒▒▒▒▒▒█░▒▓▒▒▒▒▓▒▒▒█░░░░░░░▀░░░░░█
▒▒▒▒▒▄▄█░▒▒▒▓▒▒▒▒▒▒▒█░░█▄▄█▄▄█░░█
▒▒▒▒█░░░█▄▄▄▄▄▄▄▄▄▄█░█▄▄▄▄▄▄▄▄▄█
▒▒▒▒█▄▄█░░█▄▄█░░░░░░█▄▄█░░█▄▄█

Я практик и популяризатор языково-ориентированного программирования [1]. В нём задачи решают тройкой: доменная виртуальная машина VM, доменный язык программирования DSL и алгоритмы на нём.
В этом курсе удачными фрагментами разных заметок доступно объясним причины многообразия языков и преимущества их разработки. С теорией, историей и примерами.
Вся наша работа строится вокруг VM, DSL, EBNF, отношений и графов. Мы увидим, как эти объекты соединяют вместе, получая вычислители и программы.

Читать далее

Сладкие оковы вайб-кодинга

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

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

Конечно, я не считаю, что С++ будет забыт, но с большой долей вероятности ему будет уготована нишевая роль, как сейчас это произошло с языком С, которому С++ и пришел на замену. Причем я предположил, что способ плавной замены С++ на какую то альтернативу должен происходить точно также, как сам С++ пришел на замены старому С, через транспрлайтер (sourse to source translation).

А недавно я в очередной раз решил попробовать использовать LLM при работе с большими проектами и старым легаси кодом и нужно было протестировать новые моделей в каком нибудь крупном проекта (но, чтобы это был не продуктовый код). Поэтому мой собственный проект языка программирования в виде трансплайтера оказался вполне достойным вариантом для оценки возможностей современных нейросетей на крупном проекте, таком как компилятор языка программирования. И эта статья - мои наблюдения и впечатления от использования LLM на большом и сложном проекте.

Читать далее

От регулярок к ANTLR4: три архитектурных решения на парсере бизнес-формул

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

Три года назад я писал свой первый коммерческий парсер на ANTLR4 — для бизнес-формул аналитической системы. Несколько лет спустя я бы сделал его иначе в трёх центральных местах. Разбираю каждое: левая рекурсия для приоритета операторов, Listener vs Visitor, и почему getText() для повторного парсинга — антипаттерн.

Читать далее

Nuitka 4.0: как я разогнал свой Python-скрипт на 335% и почему JIT-будущее уже на пороге

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

Представьте себе: вы запускаете свой старый добрый Python-скрипт, он привычно задумывается на пару секунд, а потом начинает работать. А теперь представьте, что тот же самый скрипт без единого изменения в коде — просто после прогона через одну утилиту — стартует почти мгновенно и работает втрое быстрее. Никакой магии, просто вышел Nuitka 4.0.

22 апреля 2026 года проект, который когда-то начинался как нишевый компилятор, дорос до мажорной версии 4.0. И это не просто «пофиксили баги, добавили пару флагов» — это реально меняет правила игры для тех, кто пишет на Python и хочет, чтобы код летал, а не ползал. По данным официальных тестов, скомпилированные скрипты показывают повышение производительности на 335% в pystone-бенчмарке по сравнению с CPython. Можете представить, что ваш веб-парсер или ML-пайплайн ускоряется втрое без переписывания на Rust.

Если совсем просто: PyInstaller просто пакует ваш скрипт вместе с интерпретатором в один файл — по сути, это архив с «батарейками». А Nuitka переписывает весь Python-код на чистый C и компилирует его в настоящий исполняемый файл. Никакой интерпретации на лету — только скомпилированный бинарник, который в теории может обогнать даже PyPy. И теперь, с версией 4.0, эта теория стала куда ближе к практике. «Раньше я думал, что ускорение от Nuitka довольно скромное... но с версией 4.0 вижу реальный прогресс», — примерно так звучат комментарии на Hacker News, и я с ними согласен.

Читать далее

Запуск сервера Minecraft (и не только) на компьютере UNIVAC из 1960-х

Время на прочтение23 мин
Охват и читатели10K

Гляньте-ка! Это я с сервером Minecraft, запущенным на компьютере UNIVAC 1219B:

А ниже будет эмулятор NES с первым отрендеренным кадром Pinball.

… и селфи, напечатанное на телетайпе при помощи техники многократной печати «overstrike».

Мы сделали ещё кучу безумных штук, и в том числе:

• Программы OCaml (!)

• Веб-сервер

• Шифрование Curve25519 + AES

• Интерпретатор BASIC

• ELIZA

• Игры наподобие Oregon Trail, Wordle и Battleship

… а также многое другое! И всё это на компьютере из 1960-х с частотой 250 кГц и всего с 90 КБ ОЗУ. Ради такого я и живу! Я одержим запуском кода в странных местах и преодолением технических ограничений. Этот проект стал для меня самым амбициозным на данный момент, он отнял у меня и других примерно восемь месяцев.

Исходники проекта я выложил на Github. Также можете посмотреть видео TheScienceElf об этом проекте!

Читать далее

Как я изобрёл велосипед: создание языка программирования с нуля ради одной игры и Telegram-бота

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

Разработка собственного языка программирования с нуля: от лексера и парсера до компилятора и интерпретатора. Разбираем архитектуру, построение AST, обратную польскую нотацию, обработку ошибок со стрелочками и двустороннюю интеграцию с Python.

А в качестве демонстрации — пишем на получившемся языке игру на Pygame и Telegram-бота с long polling. Язык называется LawScript, и он умеет больше, чем кажется.

Читать далее

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

Rust 1.95.0: макрос cfg_select!, if-let guards в match-выражениях

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

Команда Rust рада объявить о новом выпуске Rust 1.95.0. Rust — это язык программирования, который дает каждому возможность создавать надежное и эффективное программное обеспечение.

Если у вас уже установлена предыдущая версия Rust через rustup, вы можете получить 1.95.0 командой:

$ rustup update stable

Если у вас еще не установлен Rust, вы можете получить rustup на соответствующей странице нашего сайта, а также ознакомиться с подробными примечаниями к выпуску 1.95.0.

Если вы хотите помочь нам, тестируя будущие релизы, попробуйте локально переключиться на beta-канал (rustup default beta) или nightly-канал (rustup default nightly). Пожалуйста, сообщайте о любых найденных ошибках!

Что вошло в стабильный 1.95.0

Rust 1.94.0: метод array_windows у массива, ключ include в конфигурационных файлах, поддержка TOML 1.1

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

Команда Rust рада объявить о новом выпуске Rust 1.94.0. Rust — это язык программирования, который дает каждому возможность создавать надежное и эффективное программное обеспечение.

Если у вас уже установлена предыдущая версия Rust через rustup, вы можете получить 1.94.0 командой:

$ rustup update stable

Если у вас еще не установлен Rust, вы можете получить rustup на соответствующей странице нашего сайта, а также ознакомиться с подробными примечаниями к выпуску 1.94.0.

Если вы хотите помочь нам, тестируя будущие релизы, попробуйте локально переключиться на beta-канал (rustup default beta) или nightly-канал (rustup default nightly). Пожалуйста, сообщайте о любых найденных ошибках!

Что вошло в стабильный 1.94.0

Как мы погрузились в теорию компиляторов и написали свой транслятор кода

Время на прочтение16 мин
Охват и читатели11K

Всем привет! Меня зовут Егор Ермаков, я бэкенд‑разработчик в группе разработки процессинга Техплатформы городских сервисов Яндекса.

Техплатформа — это инфраструктурная платформа для всех городских сервисов Яндекса: Такси, Еды, Лавки, Доставки, а также для различных шеринговых сервисов — каршеринга, зарядных станций, самокатов и других.

Один из ключевых сервисов нашей команды — ProcaaS (Processing as a Service). Он предназначен для асинхронного выполнения динамических сценариев. Подробнее о самом сервисе, его архитектуре и роли в сетке микросервисов Такси мы рассказывали в предыдущей статье. В этом материале я хочу поделиться опытом решения одной непростой и при этом очень интересной технической задачи, с которой мы столкнулись в рамках развития ProcaaS, а именно — рассказать, как мы написали свой транслятор кода.

Читать далее

Компиляторы тоже путаются в именах

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

Это продолжение темы начатой в статье Важны ли компилятору имена, и продолженой в Ночью все кошки серы, а using'и одинаковы, и если вам нужна полная картина, как компилятор превращает текст в программу, то без понимания поиска имён (name lookup) дальше двигаться уже не получится.

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

C++ в этом месте особенно коварен. Язык рос десятилетиями, и правила поиска имён эволюционировали вместе с ним: добавлялись пространства имён, шаблоны, ADL, двухфазный поиск. Всё это не просто усложнило модель, оно сделало её местами неинтуитивной даже для опытных разработчиков, добавим сюда еще, что разные компиляторы исторически реализовывали эти правила (по-своему) по-разному, и часть этих различий до сих пор всплывает в коде.

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

Какой-то странный, этот ваш с++

Создание языка программирования дилетантом. Как это?

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

Идея создать собственный компилятор появилась у меня раньше идеи сделать собственный язык программирования. Помню, ковырялся в исходниках прошивки EV3 контроллера, чтобы сделать его эмуляцию, и в голову пришла идея -- почему бы не сделать что-то такое, но свое? Эмуляция так и не получилась адекватная, но идея написания компилятора или виртуальной машины из головы не уходила.

Читать далее

Виртуализация квантовых компьютеров: HyperQ, AWS и другие

Время на прочтение10 мин
Охват и читатели9.2K

Совсем недавно на Хабр пришла через песочницу уважаемая Елизавета @Antiquesikнаписавшая статью «Quirk: квантовый симулятор для начинающих». Елизавета, сразу уловившая, что статьи на Хабре нужно щедро и красиво иллюстрировать, рассказывает о некоторых опытах из области квантовой физики, которые этот симулятор позволяет смоделировать прямо в браузере.

Эта статья вернула меня к идее разобрать виртуализацию квантовых компьютеров и рассказать о том, какие наработки такого рода сейчас существуют и развиваются. Около трёх лет назад уважаемый @Albert_Wesker разместил на Хабре в корпоративном блоге компании «Timeweb Cloud» перевод «Уделываем классические компьютеры при помощи Borealis», где рассказал, по-видимому, о первом общедоступном квантовом компьютере на 216 кубитов, развёрнутом в облаке (также в этой статье упоминается аналогичная 8-кубитная машина X8, в которой запутаны 8 фотонов).

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

Читать далее

Зачем нужна специализация варпов. Разбор сложных случаев

Время на прочтение20 мин
Охват и читатели9.2K

Апдейт: идеи, изложенные в этой статье, позволили сформулировать оптимальные стратегии warp-специализации, описанные в научной публикации, которую можно посмотреть здесь.

Недавно я глубоко задумался о специализации варпов в контексте высокопроизводительных ядер для современных графических процессоров (GPU) на тензорных ядрах. Примеры таких процессоров — H100 и B200 от NVIDIA. Я стал полнее понимать, чего можно добиться при помощи специализации варпов, а также задался интересным вопросом: а нужна ли нам вообще специализация варпов (и вся та сложность, которую она с собой влечёт)? В итоге я пришёл к выводу, что, да, нуждаемся, но она не столь обязательна, как может показаться. В этом посте обсудим, в каких случаях без специализации варпов действительно не обойтись, а также я опишу, на каком пространстве компромиссов она зиждется, и какие границы этого пространства я вижу. Притом, что я обрисую некоторый контекст, касающийся графических процессоров, необходимый для обсуждения тем, которые мы взялись здесь рассмотреть, эту статью нельзя считать туториалом. Предполагается, что читатель имеет некоторый опыт работы с GPU и имеет опыт параллельного программирования.

Читать далее
1
23 ...