Rust를 가독성 높은 C 코드로 변환하는 Eurydice
원제 Compiling Rust to readable C with Eurydice
106 포인트댓글 32
Key Point
Rust에서 C로의 자동 변환이 고보증 소프트웨어나 C 기반 환경으로의 이식 시 검증 도구 호환성을 유지하면서 코드 동기화를 가능하게 한다.
핵심 요약
- Rust 컴파일러의 다양화 추세 속에서 Eurydice는 Rust 코드를 깔끔한 C 코드로 변환하는 야심찬 목표를 지닌 최신 프로젝트다.
- 고보증 소프트웨어(high-assurance software) 분야에서 기존 검증·규정준수 도구들이 C를 기대하므로, Eurydice는 이러한 프로젝트들의 부드러운 전환을 가능하게 한다.
- 2023년 시작된 Eurydice는 Inria(프랑스 국립 컴퓨터과학연구원)와 Microsoft 직원들이 유지보수하는 Aeneas 프로젝트의 일부이며, MIT와 Apache-2.0 라이선스 코드를 포함한다.
- Rust 프로그램을 중간표현(IR)으로 변환한 뒤 일련의 처리 과정을 거쳐 C 코드로 출력하는 일반적인 컴파일러 구조를 따른다.
- 다른 컴파일러와 달리 코드 구조를 보존하면서 Rust에만 있는 구성요소를 제거하는 데 중점을 둔다.
- gcd·lcm 함수의 예에서 생성된 C 코드는 원본 코드의 구조를 보존하고 평가 순서까지 임시 변수로 명시적으로 정의해 유지한다.
- 반면 rustc로 컴파일한 코드는 비트 연산으로 얽힌 루프가 되어 기계코드에는 적합하지만 가독성이 훨씬 낮다.
- 제네릭이 없는 C로의 변환 시 함수 단형화(monomorphization)가 필요하며, 일반적으로 매크로나 void* 인자를 사용하는 C 관례보다 여러 타입 버전을 생성한다.
- 동적 크기 타입(dynamically sized types) 처리에서 Eurydice는 유연한 배열 멤버 버전과 고정 길이 배열 멤버 버전 두 가지를 생성해, 형식 검증 시 불필요한 경계 검사 경고를 피한다.
- 이 이중 표현 방식은 런타임에는 작동하지만 C의 엄격한 별칭(strict aliasing) 규칙을 위반하므로 -fno-strict-aliasing 플래그로 컴파일하기를 권장한다.
- Eurydice는 rustc의 중간표현을 JSON으로 추출하는 Charon 도구를 사용해 직접 파서와 타입체커를 구현하지 않는다.
- 현재 const generics 같은 최신 Rust 기능에서 자주 실패하며, 소규모 자체 포함 프로그램에만 잘 동작하지만 그 범위 내에서는 원본 구조를 잘 유지한 코드를 생성한다.
- 원본 Rust 코드가 지속적으로 업데이트되고 C 버전도 자동 동기화하려는 경우에만 Eurydice 도입이 실질적 가치를 갖는다.