1 pontos por GN⁺ 3 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • 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

 
GN⁺ 3 시간 전
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

  • 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?

    • O processo de conversão insere novas verificações, então é menos “o código original era seguro” e mais um compromisso do tipo “o novo código falha de forma contundente e encerra, em vez de corromper a memória”
    • Isso aparece logo no início do artigo linkado no README
      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
    • Não há informação suficiente e, segundo o teorema de Rice, também não haverá no futuro
      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?

    • Isso é tratado com verificações em tempo de execução. Assim, no momento em que ocorre uma violação, em vez de corromper a memória, o programa pode crashar de forma segura e determinística