---
title: "Rust vs C: Segurança e Performance 2026 | Rust Brasil"
url: "https://rustlang.com.br/artigos/rust-vs-c/"
markdown_url: "https://rustlang.com.br/artigos/rust-vs-c.MD"
description: "Rust vs C: segurança de memória, FFI, performance, build systems e quando migrar de C para Rust. Comparação técnica."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Rust vs C: Segurança e Performance 2026 | Rust Brasil

Rust vs C: segurança de memória, FFI, performance, build systems e quando migrar de C para Rust. Comparação técnica.


## Introdução

C é, sem exagero, a linguagem mais influente da história da computação. Criada em 1972 por Dennis Ritchie, ela é a base de sistemas operacionais (Linux, Windows, macOS), bancos de dados (PostgreSQL, SQLite), linguagens de programação (CPython, Ruby MRI, PHP) e praticamente toda infraestrutura que sustenta a internet. **Rust** surgiu em 2015 com a missão explícita de ser uma alternativa segura para os mesmos domínios onde C reina.

Este artigo é para programadores C que avaliam Rust, engenheiros de sistemas que precisam decidir entre as duas linguagens e qualquer pessoa interessada na transformação que está acontecendo na programação de sistemas com a adoção de Rust no Linux kernel, Android e Windows.

## Tabela Comparativa

| Aspecto | Rust | C |
|---|---|---|
| **Ano de criação** | 2015 | 1972 |
| **Segurança de memória** | Garantida pelo compilador | Responsabilidade total do programador |
| **Undefined Behavior** | Impossível em safe Rust | Centenas de formas possíveis |
| **Gerenciamento de memória** | Ownership (automático, sem GC) | Manual (malloc/free) |
| **Sistema de tipos** | Rico (enums, generics, traits) | Básico (structs, unions, typedef) |
| **Build system** | Cargo (unificado) | Make, CMake, Meson (fragmentado) |
| **Gerenciamento de dependências** | crates.io (integrado) | Nenhum padrão (pkg-config, conan) |
| **Performance** | Equivalente a C | Referência de performance |
| **ABI** | Não estável (usa C ABI para FFI) | ABI estável de fato |
| **Portabilidade** | Muito boa (LLVM) | Máxima (compilador para tudo) |
| **Concorrência** | Thread safety no compilador | Sem garantias (pthreads manual) |

## Segurança de Memória: O Problema Fundamental

Segundo a NSA, Microsoft e Google, **60-70% de todas as vulnerabilidades de segurança** em software de sistemas são causadas por erros de memória em C e C++. Vamos ver os erros mais comuns:

### Buffer Overflow em C

```c
#include <stdio.h>
#include <string.h>

void processar_entrada(const char *entrada) {
    char buffer[64];
    // PERIGO: strcpy não verifica limites!
    strcpy(buffer, entrada);
    printf("Processado: %s\n", buffer);
}

int main(void) {
    // Se entrada tiver mais de 63 chars, overflow!
    char entrada_longa[256];
    memset(entrada_longa, 'A', 255);
    entrada_longa[255] = '\0';

    processar_entrada(entrada_longa); // Buffer overflow!
    return 0;
}
```

### O Equivalente Seguro em Rust

```rust
fn processar_entrada(entrada: &str) {
    // String em Rust sempre conhece seu tamanho — overflow é impossível
    let buffer: String = entrada.chars().take(64).collect();
    println!("Processado: {buffer}");
}

fn main() {
    let entrada_longa = "A".repeat(255);
    processar_entrada(&entrada_longa); // Seguro, trunca automaticamente
}
```

### Use-After-Free em C

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *nome = malloc(32);
    if (!nome) return 1;
    strcpy(nome, "Rust Brasil");

    free(nome);

    // Use-after-free: comportamento indefinido!
    // Pode funcionar, crashar ou ser explorado
    printf("Nome: %s\n", nome);

    return 0;
}
```

### Rust Impede Use-After-Free

```rust
fn main() {
    let nome = String::from("Rust Brasil");
    drop(nome); // Libera a memória explicitamente

    // ERRO DE COMPILAÇÃO: value used after move
    // println!("Nome: {nome}");
}
```

### Double Free em C

```c
#include <stdlib.h>

int main(void) {
    int *dados = malloc(100 * sizeof(int));
    if (!dados) return 1;

    free(dados);
    free(dados); // Double free: undefined behavior!

    return 0;
}
```

Em Rust, double free é **estruturalmente impossível**: cada valor tem exatamente um owner, e o `drop` é chamado automaticamente quando o owner sai de escopo. Não existe como liberar a mesma memória duas vezes.

## FFI: Interoperabilidade Rust-C

Uma das maiores vantagens do Rust é sua interoperabilidade nativa com C via FFI (Foreign Function Interface). Isso permite adotar Rust gradualmente em projetos C existentes.

### Chamando C a partir de Rust

```rust
// Declaração da função C
extern "C" {
    fn abs(n: i32) -> i32;
    fn strlen(s: *const std::ffi::c_char) -> usize;
}

fn main() {
    unsafe {
        let valor = abs(-42);
        println!("Valor absoluto: {valor}"); // 42

        let texto = std::ffi::CString::new("Olá Rust").unwrap();
        let tamanho = strlen(texto.as_ptr());
        println!("Tamanho: {tamanho}"); // 8
    }
}
```

### Expondo Rust para C

```rust
// lib.rs — biblioteca Rust utilizável por código C
use std::ffi::{c_char, CStr, CString};
use std::ptr;

#[no_mangle]
pub extern "C" fn somar_vetor(dados: *const f64, tamanho: usize) -> f64 {
    if dados.is_null() || tamanho == 0 {
        return 0.0;
    }
    let slice = unsafe { std::slice::from_raw_parts(dados, tamanho) };
    slice.iter().sum()
}

#[no_mangle]
pub extern "C" fn criar_saudacao(nome: *const c_char) -> *mut c_char {
    let nome_str = unsafe {
        if nome.is_null() {
            return ptr::null_mut();
        }
        CStr::from_ptr(nome).to_str().unwrap_or("mundo")
    };

    let saudacao = format!("Olá, {nome_str}!");
    CString::new(saudacao)
        .map(|s| s.into_raw())
        .unwrap_or(ptr::null_mut())
}

#[no_mangle]
pub extern "C" fn liberar_string(s: *mut c_char) {
    if !s.is_null() {
        unsafe {
            drop(CString::from_raw(s));
        }
    }
}
```

```c
/* main.c — código C chamando a biblioteca Rust */
#include <stdio.h>

extern double somar_vetor(const double *dados, size_t tamanho);
extern char *criar_saudacao(const char *nome);
extern void liberar_string(char *s);

int main(void) {
    double valores[] = {1.5, 2.5, 3.0, 4.0};
    double soma = somar_vetor(valores, 4);
    printf("Soma: %.1f\n", soma); /* Soma: 11.0 */

    char *msg = criar_saudacao("Comunidade");
    if (msg) {
        printf("%s\n", msg); /* Olá, Comunidade! */
        liberar_string(msg);
    }

    return 0;
}
```

Para compilar e linkar esses exemplos em diferentes plataformas, veja nosso guia de [cross-compilation](/instalacao/cross-compilation/).

## Exemplo Prático: Linked List

Uma linked list é um exercício clássico que demonstra as diferenças de gestão de memória.

### C com malloc/free

```c
#include <stdio.h>
#include <stdlib.h>

typedef struct No {
    int valor;
    struct No *proximo;
} No;

No *criar_no(int valor) {
    No *no = malloc(sizeof(No));
    if (!no) return NULL;
    no->valor = valor;
    no->proximo = NULL;
    return no;
}

void inserir(No **cabeca, int valor) {
    No *novo = criar_no(valor);
    if (!novo) return;
    novo->proximo = *cabeca;
    *cabeca = novo;
}

void imprimir(const No *cabeca) {
    const No *atual = cabeca;
    while (atual) {
        printf("%d -> ", atual->valor);
        atual = atual->proximo;
    }
    printf("NULL\n");
}

void liberar(No *cabeca) {
    while (cabeca) {
        No *temp = cabeca;
        cabeca = cabeca->proximo;
        free(temp);
    }
}

int main(void) {
    No *lista = NULL;
    inserir(&lista, 3);
    inserir(&lista, 2);
    inserir(&lista, 1);
    imprimir(lista);   /* 1 -> 2 -> 3 -> NULL */
    liberar(lista);    /* Esquecer essa linha = memory leak */
    return 0;
}
```

### Rust com Box

```rust
type Link = Option<Box<No>>;

struct No {
    valor: i32,
    proximo: Link,
}

struct Lista {
    cabeca: Link,
}

impl Lista {
    fn new() -> Self {
        Lista { cabeca: None }
    }

    fn inserir(&mut self, valor: i32) {
        let novo = Box::new(No {
            valor,
            proximo: self.cabeca.take(),
        });
        self.cabeca = Some(novo);
    }

    fn imprimir(&self) {
        let mut atual = &self.cabeca;
        while let Some(no) = atual {
            print!("{} -> ", no.valor);
            atual = &no.proximo;
        }
        println!("None");
    }
}
// Drop é chamado automaticamente — sem memory leak possível

fn main() {
    let mut lista = Lista::new();
    lista.inserir(3);
    lista.inserir(2);
    lista.inserir(1);
    lista.imprimir(); // 1 -> 2 -> 3 -> None
} // lista é automaticamente liberada aqui, recursivamente
```

Em C, esquecer de chamar `liberar()` causa memory leak. Em Rust, a memória é liberada automaticamente quando `lista` sai de escopo.

## Comparação de Performance

### Benchmarks

| Benchmark | Rust | C | Diferença |
|---|---|---|---|
| **Fibonacci(45)** | 3,2s | 3,1s | ~3% C |
| **Sort 100M inteiros** | 4,7s | 4,8s | ~2% Rust |
| **Malloc/free 10M** | 0,18s | 0,15s | ~20% C |
| **Regex 500MB** | 0,28s | 0,31s (PCRE2) | ~10% Rust |
| **HTTP req/s** | 850k (axum) | 900k (libuv) | ~6% C |

A performance é efetivamente equivalente. Rust pode ser marginalmente mais lento em alocações individuais (devido a verificações de bounds checking), mas frequentemente é mais rápido em código real graças a otimizações do iterador e melhor inlining.

## Rust no Linux Kernel

Desde 2022, o Linux kernel aceita contribuições em Rust. Isso representa uma mudança histórica:

- **Drivers de dispositivo** estão sendo escritos em Rust
- **Subsistemas novos** podem escolher Rust como linguagem
- O projeto **Rust for Linux** mantém bindings seguros para as APIs do kernel
- Linus Torvalds aprovou pessoalmente a integração

Isso não significa que o kernel será reescrito em Rust — o código C existente (30+ milhões de linhas) continuará sendo mantido. Mas novos módulos têm a opção de usar Rust para maior segurança.

## Quando Usar C

Escolha C quando:

- **O projeto já é em C**: manter consistência em bases de código existentes
- **ABI estável é obrigatório**: bibliotecas que precisam ser linkadas por qualquer linguagem
- **Plataforma sem suporte Rust**: microcontroladores muito pequenos, plataformas obscuras
- **Tamanho mínimo absoluto**: C pode produzir binários menores (sem runtime Rust)
- **Padrão da indústria**: MISRA C, AUTOSAR, POSIX strict

## Quando Usar Rust

Escolha Rust quando:

- **Projeto novo de sistemas**: sem legado para manter
- **Segurança de memória importa**: infraestrutura, networking, criptografia
- **Concorrência é necessária**: Rust garante thread safety em compilação
- **Produtividade do desenvolvedor**: Cargo, enums, pattern matching, iteradores
- **Manutenção a longo prazo**: refatoração segura, menos bugs em produção

## Conclusão e Recomendação

**Para novos projetos de sistemas em 2026**, Rust é a escolha recomendada. Você obtém performance equivalente a C com segurança de memória garantida, um sistema de build moderno (Cargo), gerenciamento de dependências integrado e abstrações de alto nível que não custam nada em runtime.

**Para projetos C existentes**, a estratégia mais inteligente é adotar Rust nos módulos novos e manter o código C existente. A FFI entre Rust e C é excelente e permite migração gradual. Não reescreva tudo de uma vez — o kernel Linux está mostrando o caminho com adoção incremental.

**Se você programa em C**, aprender Rust vai torná-lo mais produtivo e consciente sobre segurança de memória. Muitos conceitos que em C exigem disciplina e atenção manual são automatizados pelo compilador do Rust.

---

## Veja Também

- [Cross-Compilation em Rust](/instalacao/cross-compilation/) — Compile para diferentes arquiteturas e plataformas
- [Rust vs C++: Segurança sem Sacrificar Performance](/artigos/rust-vs-cpp/) — Compare com o sucessor do C
- [Rust vs Zig: Novas Linguagens de Sistemas](/artigos/rust-vs-zig/) — Outra alternativa moderna ao C
- [Entendendo o Erro E0382: Uso Após Move](/erros/e0382-uso-apos-move/) — Conceito fundamental de ownership
- [Tutorial: Ownership e Borrowing](/tutoriais/ownership-borrowing/) — O modelo de memória do Rust explicado
- [Glossário Rust](/glossario/) — Termos como FFI, unsafe, ownership e borrowing
- [Zig Brasil](https://ziglang.com.br) — Zig é outra alternativa moderna ao C com interoperabilidade nativa — conheça em português
