EnglishРусский Map

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.

Sub-pages