NoticiasLinux.com.br Notícias do Mundo GNU/Linux
26 de agosto de 2026 · por Redação

C ou Rust? O que muda entre a linguagem que sustenta o mundo e a que promete torná-lo mais seguro

C domina há 50 anos; Rust promete a mesma velocidade com segurança de memória. Entenda o debate, o caso do kernel Linux e quando usar cada uma.

Poucas discussões técnicas conseguiram a proeza de assumir, nas palavras do próprio criador do Linux, "conotações quase religiosas". A rivalidade entre C e Rust é uma delas. De um lado está a linguagem que sustenta praticamente tudo o que roda no seu bolso, na sua casa e nos servidores da internet há cinco décadas. Do outro, uma linguagem mais jovem que promete fazer o mesmo trabalho pesado sem uma das maiores fontes de dor de cabeça da computação: os bugs de memória. Não é um duelo de morte, apesar do tom acalorado que o assunto costuma provocar. É uma conversa sobre engenharia, legado e o que significa escrever software confiável em 2026. Vamos separar o barulho do que realmente importa.

O que é C e por que ela domina há meio século

C foi criada por Dennis Ritchie nos anos 1970, nos laboratórios da Bell, para escrever o sistema operacional Unix. Desde então, virou a fundação de praticamente tudo. Como resumiu bem um dos programadores veteranos ouvidos sobre o tema, "C é a base de praticamente tudo na internet". O roteador da sua casa, a geladeira conectada, o celular, os sistemas embarcados que ninguém vê funcionando: em algum nível, quase todos passam por código escrito em C. É uma linguagem que já tem mais de meio século de estrada e, portanto, passou pelo teste do tempo como poucas tecnologias em qualquer área.

O segredo dessa longevidade é uma combinação de dois fatores: simplicidade e proximidade da máquina. C é uma linguagem de baixo nível, apenas uma camada acima do assembly. Ela expõe ao programador o que de fato acontece dentro do processador: variáveis, ponteiros, estruturas, leitura direta de dados de um arquivo ou da rede. Com C você pode fazer basicamente o que quiser: acessar a memória em qualquer endereço mapeado para o seu processo, reservar memória no heap com malloc, devolvê-la com free, manipular bytes na unha. Essa liberdade quase total é justamente o que torna a linguagem tão poderosa e tão querida.

Não é à toa que o próprio Linus Torvalds, criador do kernel Linux, defende a linguagem com entusiasmo. "No fim das contas, C é uma linguagem muito simples", diz ele. "É uma das razões pelas quais eu gosto de C e por que muitos programadores de C gostam de C." Essa simplicidade tem um custo, e ele não esconde: "por ser simples, também é muito fácil cometer erros". É aqui que a história fica interessante.

O calcanhar de aquiles: os bugs de memória

A mesma liberdade que faz de C uma linguagem genial é a origem de sua maior fragilidade. Quando você é responsável por gerenciar cada byte de memória manualmente, é você quem carrega toda a responsabilidade quando algo dá errado. E dá errado com frequência, mesmo nas mãos de gente experiente. Grandes poderes vêm com grandes responsabilidades, e em C isso é literal.

Os erros mais comuns são clássicos e perigosos:

  • Estouro de buffer (buffer overflow): escrever mais dados do que o espaço reservado comporta, corrompendo memória vizinha ou abrindo brechas exploráveis por atacantes.
  • Ponteiros nulos ou soltos: acessar memória que não existe mais ou nunca existiu, o que costuma resultar naquela mensagem temida de falha de segmentação.
  • Vazamento de memória (memory leak): reservar memória e esquecer de liberá-la, fazendo o programa consumir recursos até engasgar.
  • Uso após liberação (use-after-free): continuar usando um ponteiro cuja memória já foi devolvida ao sistema.

Essas não são falhas exóticas. Uma boa fatia das vulnerabilidades de segurança catalogadas ao longo das décadas nasce exatamente desse tipo de problema. Escrever código de rede vulnerável a estouro de buffer é quase um rito de passagem de quem aprende a linguagem. Como resume um dos programadores entrevistados, com C "você pode escrever código perigoso e inseguro se não souber o que está fazendo". E, sejamos honestos, ninguém sabe o que está fazendo o tempo todo.

O que é Rust e o problema que ela resolve

Rust nasceu na Mozilla com um objetivo bem definido: oferecer o mesmo desempenho e o mesmo acesso de baixo nível de C, mas sem os bugs de memória. É, por definição, uma linguagem de programação de sistemas, feita para rodar exatamente nos lugares onde C roda: sistemas operacionais, plataformas embarcadas, qualquer contexto que exija alto desempenho e controle fino sobre o hardware.

A grande sacada de Rust é garantir segurança de memória sem usar um coletor de lixo. Isso é importante. Linguagens como Java ou Go resolvem o problema da memória com um garbage collector, um processo que roda em segundo plano recolhendo o que não é mais usado, ao custo de imprevisibilidade e sobrecarga. Rust não faz isso. Em vez disso, ela usa um sistema de posse (ownership) verificado em tempo de compilação.

A ideia central foi bem descrita por um desenvolvedor que trabalha diariamente com a linguagem: a liberação da memória está diretamente ligada à pilha. Quando você cria uma variável, ela ocupa um espaço na pilha (stack) e pode apontar para um bloco no heap. Quando essa variável sai de escopo, Rust libera automaticamente tudo o que estava associado a ela, inclusive a parte no heap. "Isso simplifica toda aquela ideia de 'ops, esqueci de liberar minha memória', ela simplesmente faz isso para você", explica. E ele faz questão de marcar a diferença: "Não é um coletor de lixo. Não é como em C, onde você precisa chamar a função manualmente. É algo intermediário."

Somam-se a isso outras decisões de design que tornam o código mais previsível. Em Rust, tudo é imutável por padrão: se você quer poder alterar uma variável, precisa dizer isso explicitamente com mut. "Qualquer coisa que não tenha a palavra mutável ao lado, você sabe com certeza que não pode ser alterada", observa o mesmo desenvolvedor. É um detalhe que torna programas grandes muito mais fáceis de ler e raciocinar.

O borrow checker: o guarda de trânsito da linguagem

O mecanismo que amarra tudo isso é o borrow checker, o verificador de empréstimos. Ele rastreia o tempo de vida de cada objeto em tempo de compilação e garante que nenhuma referência aponte para memória inválida, que dois trechos de código não modifiquem o mesmo dado de forma perigosa ao mesmo tempo, e que nada seja usado depois de liberado. Na prática, ele elimina de saída classes inteiras de erros: ponteiros nulos, referências soltas e vazamentos de memória deixam de compilar.

O ponto crucial, que separa filosoficamente as duas linguagens, é este: Rust simplesmente não deixa você compilar código que viole essas regras. Onde C entrega todo o poder e toda a responsabilidade ao programador, Rust retira um pouco da liberdade em troca de uma rede de proteção. Como colocou um dos entrevistados, "Rust tira um pouco disso de você, mas também lhe dá mecanismos de proteção. Ele impede que você tome decisões estúpidas." Existe uma válvula de escape para quando o programador precisa mesmo mexer diretamente na memória, marcada pela palavra unsafe, mas o padrão é o caminho seguro.

Desempenho: a promessa de não pagar pela segurança

A pergunta óbvia é: toda essa segurança não custa velocidade? A proposta de Rust é justamente que não. Como as verificações acontecem em tempo de compilação, e não durante a execução, o binário final roda com desempenho comparável ao de C. Rust é frequentemente descrita como extremamente rápida e eficiente em termos de memória, enfatizando desempenho, segurança de tipos e concorrência ao mesmo tempo.

Há nuances honestas nesse ponto. Um veterano de projetos como VLC e FFmpeg observou que boa parte do desempenho extremo desses softwares de mídia vem de trechos escritos à mão em assembly, onde é possível "pular para qualquer lugar na memória". Se você reescreve a parte em C em Rust por segurança, mas mantém o assembly inline para não perder velocidade, "você quebra toda a segurança", porque o modelo protegido não alcança o código de máquina bruto. Ou seja: em cenários de altíssima otimização, a fronteira entre segurança e desempenho ainda exige cuidado. Mas, para a imensa maioria das aplicações de sistema, análise de arquivos e rede, a promessa de "seguro e rápido" se sustenta.

Curva de aprendizado: liberdade fácil versus disciplina difícil

Se Rust protege tanto, por que nem todo mundo migrou? Porque essa proteção tem um preço em termos de curva de aprendizado. O borrow checker costuma transformar tarefas que parecem triviais em C em quebra-cabeças para quem está começando. "Coisas que deveriam ser simples ficam muito mais complicadas", reconhece um dos programadores. A barreira de entrada é maior, sobretudo para quem não tem experiência prévia com programação de baixo nível.

Por isso, um conselho recorrente entre desenvolvedores experientes é aprender C primeiro e Rust depois. O raciocínio é elegante. Aprendendo C, você entende como o processador realmente funciona: ponteiros, estruturas, o custo de cada operação. Você também comete os erros: trava o programa, escreve código vulnerável, esquece de liberar memória. Aí, ao chegar em Rust, a frustração com as restrições do borrow checker vira alívio, porque você entende exatamente quais desastres ele está evitando. "Aprender C, mesmo que você não o utilize, o torna um programador melhor", diz um dos entrevistados. Rust, aprendido depois, faz o resto do sentido.

O caso do kernel Linux: onde o debate ficou público

Nenhum episódio expôs tanto essa tensão quanto a chegada de Rust ao Linus Torvalds e seu kernel. Historicamente escrito 100% em C, o Linux passou a aceitar código em Rust por meio do projeto "Rust for Linux". A infraestrutura inicial foi integrada, tem crescido, mas, como o próprio Torvalds admitiu, ainda não há nenhuma parte crítica do kernel que dependa de Rust. A expectativa dele é que drivers e até alguns subsistemas importantes comecem a adotá-lo de forma ativa nos próximos anos.

Para Torvalds, a decisão foi tanto técnica quanto cultural. Fez sentido do ponto de vista de engenharia, mas ele destaca outra motivação: não deixar o projeto estagnar. "Estou trabalhando no kernel há 32 anos, e isso é muito tempo para trabalhar em uma única coisa", disse. "É muito fácil ficar preso na rotina e dizer que está funcionando perfeitamente bem." Experimentar Rust é, para ele, uma forma de manter os desenvolvedores em movimento.

A transição, porém, não tem sido tranquila. Um dos mantenedores do projeto Rust para Linux chegou a se demitir após quase quatro anos, alegando "absurdos não técnicos" e falta de energia para lidar com eles. Houve atrito entre a turma que escreve drivers em Rust e mantenedores mais antigos da infraestrutura em C. Torvalds analisa o conflito com serenidade e até bom humor, comparando-o às antigas guerras entre editores de texto: "Isso me lembra de quando eu era jovem e as pessoas discutiam sobre VI versus Emacs." Ele reconhece a raiz técnica da resistência: uma arquitetura segura em relação à memória faz certas exigências sobre o tratamento de erros que muitos veteranos, acostumados ao modelo de C, relutam em aceitar. Mas encara tudo como parte saudável do processo. "Mesmo que se torne um fracasso, e não acho que será, é assim que se aprende."

Vale notar que essa discussão acontece à luz do dia justamente porque o Linux é software livre: o código, os patches e até as brigas entre mantenedores são públicos, o que dá ao debate uma transparência rara em projetos fechados.

"Não reescreva tudo": a lição da interoperabilidade

Um alerta importante vem de quem já colocou Rust em produção dentro de bases de código antigas. A comunidade Rust tem uma ala entusiasmada que acredita ser preciso reescrever tudo, porque "tudo ficará melhor com Rust". A experiência prática recomenda cautela. Rust brilha em projetos novos, começados do zero. Já em interoperar com peças existentes, o caminho é espinhoso.

O argumento é sólido e vale para qualquer linguagem: escrever código é uma ordem de grandeza mais fácil do que ler código. Quando alguém se depara com uma base madura e complexa, o instinto é dizer "isso está confuso, vou reescrever". Mas boa parte da lógica de negócio, das decisões e das gambiarras justificadas está embutida ali de forma não documentada. Você chega rápido a 80% ou 90% de uma reescrita, e então descobre que "esse 1% restante leva 99% do tempo". Rust é excelente para módulos novos de análise de arquivos e rede, onde o borrow checker faz maravilhas. Substituir por atacado um sistema que já funciona há décadas é outra conversa.

Afinal, quando usar cada uma?

Não existe resposta única, mas dá para traçar orientações claras:

  • Escolha C quando precisar de máxima simplicidade, portabilidade universal e integração com o oceano de código legado que move o mundo. Sistemas embarcados minúsculos, firmware, projetos que já vivem em C e ecossistemas maduros pedem a linguagem de Ritchie.
  • Escolha Rust em projetos novos onde segurança de memória e concorrência confiável são prioridade desde o primeiro dia: ferramentas de sistema, serviços de rede, parsers, componentes críticos que não podem falhar por um ponteiro solto.
  • Para aprender, o caminho sugerido por veteranos é C primeiro, para entender a máquina, e Rust depois, para entender por que as proteções existem.
  • Para migrar, prefira a coexistência gradual, um módulo por vez, à reescrita total.

É bom lembrar que as opções de linguagem para programação de sistemas sempre foram poucas. Como observou Torvalds, quem escreve sistemas operacionais precisa de algo que lide com problemas de baixo nível, o que reduz drasticamente o cardápio: ou assembly, ou C, ou Rust. Nesse universo restrito, as duas linguagens deste artigo são, hoje, as protagonistas.

Coexistência, não guerra

O jeito mais honesto de encerrar o debate "C ou Rust" é reconhecer que a pergunta talvez esteja mal formulada. Não se trata de uma linguagem matar a outra. C não vai desaparecer: são cinquenta anos de código rodando em toda parte, de chips 5G a firmwares dentro de aparelhos que você nem imagina, e essa base não some da noite para o dia. Rust também não é modismo passageiro: resolve um problema real e caro, os bugs de memória, e faz isso sem abrir mão do desempenho.

A leitura mais madura é a de convivência. C segue como a fundação simples, veloz e onipresente, enquanto Rust se firma como a opção moderna para quando a segurança de memória é inegociável. O próprio kernel Linux, o coração do software livre, é hoje o palco onde essa convivência está sendo testada na prática, com tropeços e aprendizados à vista de todos. Não é uma questão de escolher um lado e torcer pela derrota do outro. É entender as forças de cada ferramenta e usar a certa para cada trabalho. No fim, quem ganha com boas linguagens bem empregadas é o software que todos nós usamos.

📬 Receba no seu e-mail As principais notícias de Linux e software livre, sem custo.
« todos os artigos