C é o melhor (2025)
(sqlite.org)- O SQLite é um mecanismo de banco de dados leve implementado em C desde 2000, e não há planos de reescrevê-lo em outra linguagem
- O C é considerado a linguagem mais adequada para o SQLite em termos de desempenho, compatibilidade, mínimas dependências e estabilidade
- Linguagens orientadas a objetos (C++, Java etc.) têm grandes limitações de chamada entre linguagens, e uma abordagem procedural pode ser mais simples e rápida
- Linguagens “seguras” como Rust ou Go ainda não estão maduras o suficiente e não se alinham à estratégia de qualidade do SQLite (ex.: testes com 100% de cobertura de branches, recuperação de OOM)
- A possibilidade de portar para Rust continua em aberto, mas só se várias condições forem atendidas, como maturidade, compatibilidade, desempenho e suporte de ferramentas
1. Por que C é a melhor opção
- O SQLite foi implementado desde o início em C padrão em 29 de maio de 2000, e até hoje não há plano de migrá-lo para outra linguagem
- O texto aponta desempenho, compatibilidade, baixa dependência e estabilidade como razões pelas quais o C é adequado para a implementação do SQLite
1.1 Desempenho
- O SQLite é uma biblioteca de baixo nível usada intensivamente, portanto alta velocidade é essencial
- Como exemplo, o desempenho é demonstrado nos documentos “Internal Versus External BLOBs” e “35% Faster Than The Filesystem”
- O C oferece controle próximo ao hardware, a ponto de ser chamado de “linguagem assembly portátil”, ao mesmo tempo em que mantém portabilidade entre plataformas
- Outras linguagens afirmam ser “tão rápidas quanto C”, mas nenhuma afirma ser mais rápida que C
1.2 Compatibilidade
- Quase todos os sistemas oferecem capacidade de chamar bibliotecas escritas em C
- Por exemplo, no Android, aplicações Java podem chamar o SQLite por meio de um adaptador
- Se o SQLite tivesse sido escrito em Java, não poderia ser usado em apps de iPhone baseados em Objective-C ou Swift
1.3 Baixa dependência
- Bibliotecas escritas em C têm pouquíssimas dependências de runtime
- Na configuração mínima, o SQLite precisa apenas das seguintes funções da biblioteca padrão de C
- memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp()
- Mesmo em um build completo, usa basicamente malloc(), free() e entrada/saída de arquivos
- Em contraste, linguagens modernas exigem runtimes de vários MB e milhares de interfaces
1.4 Estabilidade
- O C é uma linguagem antiga e com poucas mudanças, oferecendo comportamento claro e previsível
- Ao desenvolver um mecanismo de banco de dados pequeno, rápido e confiável como o SQLite, é importante que a especificação da linguagem não mude com frequência
2. Por que não foi escrito em uma linguagem orientada a objetos
-
Alguns desenvolvedores acham que sistemas complexos só podem ser implementados com linguagens orientadas a objetos, mas o SQLite mostra o contrário
-
Bibliotecas escritas em C++ ou Java normalmente só podem ser usadas por aplicações escritas na mesma linguagem
- Já bibliotecas em C podem ser chamadas a partir de praticamente qualquer linguagem
-
Orientação a objetos é um padrão de projeto, não a linguagem em si, e estruturas orientadas a objetos também podem ser implementadas em C
-
Orientação a objetos nem sempre é a melhor escolha; em alguns casos, código procedural é mais simples e vantajoso em manutenção e desempenho
-
No início do desenvolvimento do SQLite (começo dos anos 2000), o Java ainda era imaturo, e o C++ tinha sérios problemas de compatibilidade entre compiladores
- Na época, C era claramente a melhor escolha, e ainda hoje quase não há benefício em reescrever
3. Por que não foi escrito em uma “linguagem segura”
- Recentemente, “linguagens seguras” como Rust e Go ganharam destaque, mas o SQLite continua em C
- Durante os primeiros 10 anos do SQLite, essas linguagens seguras não existiam
- É possível reescrever em Go ou Rust, mas há risco de novos bugs e perda de desempenho
- Linguagens seguras inserem branches adicionais, como verificação de limites de arrays
- Em código correto, esses branches não são executados, então não é possível fazer testes com 100% de cobertura de branches
- A maioria das linguagens seguras interrompe o programa em caso de falta de memória (OOM)
- O SQLite é projetado para se recuperar normalmente mesmo em OOM, o que entra em conflito com esse comportamento
- As linguagens seguras existentes são todas novas e ainda mudam rapidamente
- O SQLite prefere uma linguagem antiga e estável
4. Possibilidade de portar para Rust
- Existe a possibilidade de reescrever o SQLite em Rust, mas portá-lo para Go é quase impossível
- Motivo: Go não gosta de assert()
- Condições prévias para uma migração para Rust
- Rust precisa amadurecer mais e desacelerar seu ritmo de mudanças para se tornar uma “linguagem antiga e estável”
- Rust precisa ser capaz de gerar bibliotecas de uso geral que possam ser chamadas por todas as linguagens
- Precisa gerar código objeto capaz de funcionar também em dispositivos embarcados sem sistema operacional
- Precisa ter um ecossistema de ferramentas que suporte testes com 100% de cobertura de branches
- Precisa fornecer um mecanismo de recuperação de OOM
- Precisa demonstrar uma implementação sem perda de desempenho em relação ao C
- Desenvolvedores que acham que Rust atende a essas condições podem entrar em contato diretamente com a equipe do SQLite para discutir
5. Conclusão
- O SQLite é um mecanismo de banco de dados pequeno, rápido e confiável, e as características da linguagem C se alinham a esse objetivo
- Migrar para uma linguagem orientada a objetos ou segura não traz ganhos práticos em compatibilidade, desempenho ou controle de qualidade
- A simplicidade e estabilidade do C sustentam a manutenção de longo prazo e a confiabilidade do SQLite
8 comentários
De qualquer forma, é um projeto que nem aceita PR mesmo... então eles usam o que querem usar.
Se o cenário for compacto, não existe linguagem que substitua C, C++ e Rust. É só que quase não há desenvolvedores que se identifiquem com a ideia de desenvolver se preocupando com overflow em nível de bits ou com invasões em
structs oumaps.O título é muito sensacionalista. Se vocês lerem o texto original, vão ver que é um artigo sobre por que C é a linguagem mais adequada para o desenvolvimento do sqlite. Espero que todos se acalmem.
Nossa, até o próprio texto foi escrito há 7 anos, né? Parece que atualizaram só algumas partes em 2025, acrescentando conteúdo depois... 🤦
O importante é conseguir fazer esse julgamento de usar a linguagem adequada para cada situação de desenvolvimento; colocar um título desses, como se uma linguagem específica fosse sempre a melhor, é nível de pensamento de alguém que mal terminou o ensino fundamental...
Acho que a maior vantagem do C é tocar diretamente na essência de que “o computador é uma sequência de bits”. Há um certo encanto na filosofia simples do C e no uso agressivo de
reinterpret casting, que faz com que o usuário quase sempre consiga saber para qual código de máquina aquilo será traduzido. Não é que seja por ser C que ele pode ser chamado por todas as linguagens; o que pode ser chamado é a ABI, e no C isso acontece apenas porque é previsível — ou precisa ser previsível — quais sequências de bits entram e saem. Também acho importante, ao discutir viabilidade de implementação, distinguir se algo é impossível em uma máquina de Turing ou apenas impossível na linguagem ou framework que estamos usando agora.Opiniões do Hacker News
Acho que não é preciso justificar por que nem todo projeto ou programador usa Rust ou Zig
Há uma tendência de empurrar essas linguagens em excesso no Hacker News e em outras plataformas
Se já se está obtendo bons resultados com C e os usuários estão satisfeitos, não há motivo para gente de fora ficar dando pitaco
É um fluxo natural que pessoas interessadas em evolução tecnológica explorem o potencial de novas linguagens
Mas, embora quem está de fora tenha liberdade para opinar, o projeto não tem obrigação de escutar
Rust reduz a exposição a bugs, mas os mesmos tipos de bug ainda existem
Desenvolvedores C tendem a reagir com mais sensibilidade a condições de corrida, e no Rust há o risco de confiar demais nas anotações de “segurança”
Além disso, no Rust correções nem sempre são simples, o que pode aumentar o peso de refatoração
No fim, Rust é uma linguagem interessante, mas não é uma solução universal, e não deveria ser imposta
Linguagens como Rust e Zig têm a intenção de se afastar de padrões tradicionais de orientação a objetos
OOP já foi atraente como uma estrutura conceitual que trazia uma espécie de “iluminação”, mas na prática muitas vezes aumenta a complexidade e prejudica a modularidade
Assim como é natural usar uma furadeira elétrica em vez de uma manual, se existe uma ferramenta melhor, é natural usá-la
Mas as ferramentas e a formação para escrever código C seguro também precisam evoluir o suficiente
Sou um Rustacean bastante sério, mas não acho racional reescrever todo projeto em Rust
Se um projeto em C já foi bem validado, migrá-lo para Rust no curto prazo pode até aumentar a chance de bugs
Ainda assim, algumas iniciativas estão tentando reescrever em Rust; por exemplo, há o Limbo: um projeto que reescreve completamente o SQLite em Rust
Um dos principais pontos fortes do SQLite é justamente permitir acesso simultâneo por vários processos, e sem isso o alcance de uso fica menor
Basta criar uma nova versão por conta própria e testar se dá certo
Já tive experiência migrando o RediSearch para Rust
Isso aconteceu porque havia muitas vulnerabilidades CVE recentemente
Se o SQLite não tem esse tipo de problema, fica mais fraco o motivo para migrá-lo para Rust
Acho que vai levar décadas para entender de fato as forças e limitações do Rust
Especialmente em aplicações GUI, a utilidade do Rust ainda não está clara
Talvez o Rust só chegue ao mesmo nível de confiança por volta de 2040
Como o Linus mencionou, o Rust precisa de um mecanismo de recuperação de OOM (Out of Memory)
Dá para ver a discussão relacionada neste link da LKML
mallocdiretamenteEm código embarcado ou de kernel, dá até para desativar totalmente os recursos de alocação
Ou seja, o Rust já oferece controle total sobre a memória
A afirmação de que “não existe linguagem de propósito geral mais rápida que C” é uma comparação limitada, que ignora o tempo do desenvolvedor
Em vez de gastar 5 horas em C para fazer um programa de 4 segundos, pode ser mais realista fazer em 5 minutos em outra linguagem um programa de 5 segundos
Quanto maior o número de usuários, mais valor acumulado até pequenas diferenças de desempenho têm
O Rust ainda está longe de se tornar uma linguagem “entediante e estável”
Enquanto o C é gerido por um comitê conservador que preserva compatibilidade com rigor, o Rust prioriza inovação acima de compatibilidade para resolver problemas
Código de versões antigas continua podendo ser compilado com compiladores novos
Acho isso melhor do que a abordagem do C++, que continua carregando recursos do passado
Já linguagens projetadas por comitês, como C++ ou Common Lisp, ganharam mais complexidade
O Rust também é grande, então convém usá-lo com cautela em sistemas embarcados ou centrais
Concordo com a postura de “não mexer no que já funciona bem”
A história da evolução das linguagens parece uma repetição de tentativas de resolver problemas que acabam criando nova complexidade
C é um caso representativo da filosofia “Worse is Better”, e teve sucesso por décadas graças à simplicidade
Rust, por outro lado, busca a “Right Thing™”
Hoje, como o peso de implementar tudo na mão diminuiu na maioria dos ambientes, isso pode ser uma escolha melhor
Mas não há necessidade de migrar à força projetos que já deram certo
Em projetos novos, há uma boa chance de Rust ser a melhor escolha
A simplicidade e estabilidade do C são vantagens subestimadas
Acho melhor lapidar a biblioteca padrão ou o ecossistema do que continuar mudando a linguagem em si
Não basta simplicidade; garantia de comportamento determinístico também é importante
Por exemplo, gosto de recursos como designated initializer, compound literal, alignas e memset_explicit
Pessoalmente, ainda acho que C é o melhor
Rust tem muitas boas ideias, mas também é uma linguagem com desvantagens bem claras
Ainda existe um clima em que é difícil discutir com frieza os problemas do Rust
Por exemplo, pode haver questões como curva de aprendizado ou complexidade de empacotamento
A ideia de que “todo sistema pode chamar bibliotecas C” já não é mais verdade
Rust e Zig também atendem a esse requisito
Porém, a biblioteca padrão do Rust muitas vezes entra em pânico em caso de OOM em vez de se recuperar, e a documentação também é insuficiente
extern "C"ouexportpara ter compatibilidade com a ABI de CCaso contrário, a ABI não é definida e pode até ser mais instável que C++
Especialmente em distribuições Linux que empacotam crates Rust, esse problema pode ser ainda maior