Fil-C
- title
- Fil-C
- type
- toolbox
- summary
- Безопасный по памяти компилятор C/C++, снабжающий каждый указатель capability с проверкой границ и GC без переписывания исходного кода
- tags
- c, cpp, memory-safety, compiler, llvm
- language
- C/C++
- license
- Apache-2.0
- created
- 2026-04-18
- updated
- 2026-04-18
- lang
- ru
- translation_of
- fil-c
- source_updated
- 2026-04-18
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Безопасная по памяти реализация C/C++. Fil-C добавляет проход LLVM IR, который переписывает операции с указателями: рядом с каждым указателем передаётся теневая capability (структура AllocationRecord*), при каждом разыменовании проверяются границы, а сборщик мусора управляет временем жизни записей о capability. В итоге C/C++ переживает выход за границы массива, use-after-free и type confusion без переписывания исходного кода.
Как это устроено
Три идеи по слоям:
- Теневая capability на каждый указатель. Каждый указатель идёт в паре с
AllocationRecord*, который отслеживает границы аллокации (visible_bytes,length). При разыменовании границы проверяются по этой записи. Полный разбор есть в simplified-model-of-fil-c. - Параллельная теневая куча для сохраняемых указателей. У каждой аллокации есть массив
visible_bytes(пользовательские данные) и массивinvisible_bytes(такого же размера, с элементами типаAllocationRecord*). Когда пользовательский код читает или записывает указатель в память, Fil-C параллельно читает или записывает capability по соответствующему индексу. Именно так capability сохраняются при прохождении через память. - Параллельный конкурентный инкрементальный GC (FUGC). Объекты AllocationRecord никогда не освобождаются явно - ими занимается сборщик мусора. Поэтому забытый
freeне приводит к утечке, а use-after-free становится безопасным (освобождённые записи канонизируются в единый sentinel нулевой длины).
Дополнительные инженерные решения: локальные переменные, прошедшие escape-анализ, автоматически перемещаются в кучу; указатели на функции снабжены отдельным флагом capability с единым ABI; а атомарные операции над указателями используют специальный lowering для сохранения атомарности при парном чтении.
См. pointer-provenance - Fil-C представляет собой наглядную систему, в которой семантика provenance становится наблюдаемой, поскольку одинаковые по значению указатели могут нести разные AllocationRecord*.
Сценарии использования
- Устаревший C/C++, которому нужна безопасность по памяти без полного переписывания - как правило, в качестве промежуточного шага перед миграцией.
- Более надёжная альтернатива ASan для поиска ошибок работы с памятью.
- Безопасное вычисление на этапе компиляции в языках вроде Zig, где compile-time и runtime используют один и тот же язык.
- Наглядный пример для изучения концепций модели памяти, таких как provenance.
Ограничения
- Высокие накладные расходы. Каждое разыменование требует проверки границ, а каждая операция чтения или записи указателя удваивается. Оптимизации компенсируют часть потерь, но далеко не всё.
- Навязывает GC для C/C++. Для систем, где паузы GC недопустимы, Fil-C не подойдёт.
- Изменение ABI. Функции принимают парные аргументы
(pointer, AllocationRecord*); для взаимодействия с немодифицированным C-кодом требуются обёртки. - Особенность семантики
memmove. Выровненный многобайтовыйmemmoveпереносит теневую память вместе с байтами пользователя; невыровненное или побайтовое копирование этого не делает. Из-за этого можно незаметно потерять capability, если код полагается на невыровненное размещение структур в памяти.
Связанные страницы
- simplified-model-of-fil-c - пошаговое введение, на котором основана эта страница
- pointer-provenance - концепция модели памяти, которую демонстрирует Fil-C
- win32-stable-abi, abi-stability - контраст: стабильность ABI как отсутствие принудительной безопасности
- yk - ещё один проект, переписывающий LLVM IR, но ради JIT, а не безопасности
Сайт проекта: fil-c.org. Технические подробности: Invisicaps. Сборщик мусора: FUGC.