- Cpp2Rust é um tradutor orientado por sintaxe baseado na AST do clang, que converte automaticamente entrada em C++ em código Rust totalmente seguro
- O processo de tradução analisa arquivos C++ com o clang para gerar uma AST, percorre essa AST gerando código Rust como string e depois produz um único arquivo
.rs com rustfmt
- O padrão é o modelo de contagem de referências e, para depuração e comparação de desempenho, também é possível gerar Rust unsafe com
--model=unsafe
- O código gerado depende da biblioteca de runtime
libcc2rs, e ponteiros C são convertidos em Ptr<T>, que modela null, aritmética e aliasing
- A tradução de programas inteiros exige
compile_commands.json, e projetos CMake podem gerá-lo com a flag CMAKE_EXPORT_COMPILE_COMMANDS=ON
Conversão automática de C++ para Rust seguro
- Cpp2Rust é uma ferramenta que traduz automaticamente C++ para Rust totalmente seguro
- É um tradutor orientado por sintaxe baseado na AST do clang
- O algoritmo de tradução é descrito no artigo publicado na PLDI 2026, Cpp2Rust: Automatic Translation of C++ to Safe Rust
Pipeline de tradução
- O arquivo C++ de entrada é primeiro analisado pelo clang para gerar a AST
- Em seguida, a AST é percorrida e o código Rust é emitido como string
- Quando necessário, são inseridas chamadas para a biblioteca de runtime
libcc2rs
- Um exemplo é o tratamento de raw pointer semantics
- Por fim,
rustfmt é usado para organizar o código Rust em um único arquivo .rs
Modelos de Rust seguro e Rust unsafe
- O comportamento padrão usa o modelo de contagem de referências e gera saída em Rust totalmente seguro
- Também é fornecido um gerador de Rust unsafe
- O argumento de linha de comando é
--model=unsafe
- O objetivo é depuração e comparação de desempenho
Biblioteca de runtime libcc2rs
- O código gerado depende de uma biblioteca de runtime projetada para simplificar o processo de tradução
- Ponteiros C são convertidos para o tipo
Ptr<T> fornecido por libcc2rs
Ptr<T> modela a semântica de ponteiros em C
- null
- aritmética de ponteiros
- aliasing
- O borrow checker do Rust é atendido por meio de operações de runtime verificadas
Fluxo de build e execução
- O exemplo de instalação de dependências no Ubuntu inclui
libclang-22-dev, clang++-22, ninja-build, cmake, ruff
- O build segue a sequência
cmake -GNinja .., ninja, ninja check
- O comando para traduzir um único arquivo tem a seguinte forma
./build/cpp2rust/cpp2rust --file=<file>.cpp -o=<file>.rs
- Para gerar Rust unsafe, execute da seguinte forma
./build/cpp2rust/cpp2rust --file=<file>.cpp -o=<file>.rs --model=unsafe
Exemplo mínimo e tradução de programa completo
- O exemplo
printf("hello world\n") de hello.cpp é convertido em código que inclui println!("hello world") em Rust
- O
hello.rs convertido é compilado e executado da seguinte forma
rustc hello.rs -L ../libcc2rs/target/debug
./hello
- A tradução de um programa completo exige
compile_commands.json
- No CMake,
compile_commands.json pode ser gerado com a seguinte flag
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
- O comando para traduzir um programa completo tem a seguinte forma
./build/cpp2rust/cpp2rust --dir=<dir> -o <output>.rs
<dir> deve ser o diretório que contém compile_commands.json
Comandos de teste
- Todos os testes são executados com
ninja check
- Os testes unitários são executados com
ninja check-unit
- Os testes unitários de
libcc2rs são executados com ninja check-libcc2rs
- Os testes unitários de
libcc2rs-macros são executados com ninja check-libcc2rs-macros
- Para regenerar a saída esperada após mudanças intencionais, use
REPLACE_EXPECTED=1 ninja check-unit
1 comentários
Comentários no Lobste.rs
Em fevereiro deste ano, assisti a uma apresentação de Dan Wallach, na qual ele apresentou o projeto TRACTOR (Translating All C to Rust) da DARPA [1] [2] [3]
Dizem que a equipe do MIT Lincoln Laboratory está conduzindo os testes e a avaliação do programa de pesquisa
Sei que ainda está em fase de pesquisa, mas tenho muito interesse nesse tema e estou bastante curioso para ver que tipo de ferramentas e ideias vão surgir
Parece que isso poderia realmente eliminar muitos bugs “pequenos” vindos do gerenciamento de memória
[1] https://www.darpa.mil/research/programs/translating-all-c-to-rust
[2] https://github.com/DARPA-TRACTOR-Program
[3] https://ll.mit.edu/r-d/projects/…
Interessante. Seria muito bom ver uma ou duas demos de bibliotecas ou apps que os autores tenham convertido com isso e que eles próprios considerem interessantes
Por exemplo, olhando https://github.com/Cpp2Rust/cpp2rust-testsuite/…, pode até ser Rust seguro, mas definitivamente é difícil chamá-lo de Rust idiomático
Não entendo bem por que é necessária uma etapa de conversão. Se há informação suficiente para converter para Rust com segurança de memória, então não haveria também informação suficiente para garantir, por análise estática, que o C++ é seguro?
Ele diz que cerca de 70% das vulnerabilidades de segurança em softwares amplamente distribuídos vêm de bugs de segurança de memória em linguagens como C e C++, e que, apesar de décadas de investimento em mitigações como análise estática, sanitizers e isolamento por hardware, atacantes ainda exploram operações de memória inseguras
O artigo explica que, no longo prazo, uma solução promissora é mover bases de código C++ existentes para linguagens com segurança de memória, como Rust, mas fazer isso manualmente é caro demais e propenso a erros
Ele afirma que o Cpp2Rust é o primeiro sistema capaz de converter automaticamente programas C++ em código Rust funcionalmente equivalente e com segurança de memória
Trocando parte do desempenho por segurança, ele resolve a incompatibilidade fundamental entre referências alias irrestritas do C++ e o modelo de ownership do Rust inserindo verificações de ownership e mutabilidade em tempo de execução, preservando a semântica e garantindo segurança
Para reduzir o overhead das verificações dinâmicas, eles também criaram uma otimização de source-to-source para código Rust, que remove operações redundantes de ownership e recupera uma parte considerável do desempenho perdido
Portanto, a motivação não é simplesmente provar segurança, mas portar para Rust e facilitar que o desenvolvimento futuro passe a ser em Rust
A ideia de projetos como esse é criar um ponto de partida para refatorar para Rust idiomático, e assim tornar o código analisável
Com sorte, também será possível remover as verificações em tempo de execução ou partes inseguras do código convertido
Você poderia dizer que bastaria refatorar o C++ para um “formato de Rust” e torná-lo analisável do mesmo jeito, mas C++ tem semânticas diferentes que permitem muito mais flexibilidade, o que pode fazer os caminhos a analisar crescerem exponencialmente ou levar a análise estática a becos sem saída ambíguos
Seria preciso prometer não fazer coisas difíceis para o analisador estático e não explorar casos-limite; para isso, daria para criar um dialeto de C++ com semântica mais restrita e anotações adicionais
Circle/Safe C++ mostrou que isso é possível, mas como o WG de C++ rejeitou fortemente essa direção, as opções que restam são escrever por conta própria um dialeto de C++ parecido com Rust e sem suporte, ou simplesmente usar Rust
Como exatamente isso funciona quando o código de entrada em si é inseguro?