Что такое Zig и зачем он нужен
Знакомимся с Zig — системным языком, который претендует на роль «лучшего C».
Zig — компилируемый системный язык программирования общего назначения, спроектированный как современная замена C: без скрытых аллокаций памяти, без скрытого потока управления и с выполнением кода на этапе компиляции вместо макросов.
Си правит системным программированием почти полвека. На нём написаны ядра операционных систем, компиляторы, базы данных и встраиваемые прошивки. Но у C есть болезни, с которыми программисты борются десятилетиями: разыменование NULL, переполнение целых чисел, неопределённое поведение, утечки памяти, висячие указатели. Современные языки вроде Rust решают эти проблемы, но платят за это сложностью — borrow checker требует переучиваться мыслить. Zig выбирает другой путь.
Идея Zig в одном предложении
Андрей Келли начал разрабатывать Zig в 2015 году с простой целью: взять C, убрать его худшие ловушки, но не превращать язык в монстра. Zig остаётся маленьким и прямолинейным. В нём нет препроцессора, нет перегрузки операторов, нет скрытых вызовов конструкторов и деструкторов, нет сборщика мусора. То, что вы видите в коде, — это ровно то, что выполнится.
Три принципа явности
Философия Zig держится на трёх «нет», которые отличают его от C++ и Rust.
Нет скрытым аллокациям памяти
В C++ строка std::vector<int> v; v.push_back(5); может незаметно выделить кучу памяти. В Zig любая функция, которая выделяет память, обязана принимать аллокатор явным параметром. Если функция не получила аллокатор — она физически не может тронуть кучу. Это значит, что во встраиваемой системе без динамической памяти вы сразу видите, какой код нарушает правила.
Нет скрытому потоку управления
В Zig нет исключений, которые незаметно раскручивают стек, нет перегрузки операторов, которая прячет вызов функции за знаком +, нет макросов, которые подменяют код. Если вы видите вызов функции — это вызов именно этой функции. Поток управления читается глазами без сюрпризов.
Нет препроцессору и макросам
Вместо макросов C и шаблонов C++ Zig предлагает comptime — обычный код Zig, который выполняется во время компиляции. Это и метапрограммирование, и дженерики, и кодогенерация на одном понятном языке.
const std = @import("std");
pub fn main() void {
std.debug.print("Zig: явность важнее магии\n", .{});
}
Вывод:
Zig: явность важнее магии
Как работает под капотом
Zig компилируется в нативный машинный код через LLVM (а в новых версиях — через собственный бэкенд). Получается обычный бинарник без рантайма и без зависимостей, как у C. При этом компилятор Zig умеет ещё и собирать код на чистом C — он включает в себя полноценный кросс-компилятор C. Поэтому Zig нередко используют просто как удобную замену gcc или clang для кросс-сборки.
Частые ошибки
Главное заблуждение новичка из мира C++ — ждать, что стандартная библиотека сама выделит память «как обычно». В Zig почти каждый контейнер требует, чтобы вы передали ему аллокатор. Второе заблуждение — искать макросы и #ifdef. Их нет: условную компиляцию делают через comptime и обычный if.
Итог
- Zig — системный язык, спроектированный как современная замена C.
- Три кита: нет скрытых аллокаций, нет скрытого потока управления, нет макросов.
comptimeзаменяет и шаблоны, и препроцессор.- Компилятор Zig умеет собирать ещё и C, работая как кросс-компилятор.