Bem-vindo ao Blog da DMarkInfo

Conteúdos e novidades sobre Tecnologia da Informação.

Por que as urnas eletrônicas ainda usam C/C++ em vez de linguagens modernas como Go?

Postado por Eduardo Marques em 16/05/2026
Por que as urnas eletrônicas ainda usam C/C++ em vez de linguagens modernas como Go?

Durante muito tempo eu tive uma visão extremamente simplista sobre as urnas eletrônicas brasileiras. Na minha cabeça, era “só um computador velho rodando um software qualquer”. Mas quanto mais comecei a estudar sistemas embarcados, segurança de software e arquitetura de aplicações críticas, mais percebi que a realidade é muito mais complexa do que parece. E sinceramente? Faz bastante sentido.

As urnas não são apenas computadores comuns executando uma aplicação gráfica. Elas são dispositivos construídos para operar de forma extremamente controlada, isolada e previsível. Isso muda completamente as decisões de engenharia envolvidas no projeto.

Quando a gente olha o stack tecnológico delas, começa a entender por que certas escolhas continuam existindo até hoje — inclusive o fato de o núcleo do sistema ainda depender fortemente de C e C++.

 

A urna não é “um PC comum”

Esse talvez seja o maior erro de percepção de muita gente. A urna eletrônica é um sistema embarcado customizado. Ela não foi projetada para ser flexível como um desktop, notebook ou servidor. Muito pelo contrário: ela foi criada para executar uma única função da forma mais previsível possível.

As versões mais recentes utilizam hardware muito mais moderno do que muita gente imagina. Modelos como a UE2020 e UE2022 possuem SoCs muito mais rápidos que gerações anteriores, memória DDR3L, armazenamento M.2 e módulos criptográficos dedicados. Além disso, o sistema operacional utilizado é o Uenux, uma versão customizada do Linux mantida pelo próprio TSE.

E aqui existe um detalhe extremamente importante: a urna é um equipamento offline. Ela não possui Wi-Fi, Bluetooth ou qualquer interface tradicional de comunicação em rede ativa durante a votação. Isso reduz drasticamente a superfície de ataque do sistema. Em segurança, remover complexidade quase sempre aumenta confiabilidade, e a arquitetura da urna segue exatamente essa filosofia.

 

O motivo de C ainda dominar sistemas críticos

Hoje existe uma tendência natural de achar que linguagens modernas deveriam substituir tudo que é antigo. Mas sistemas críticos não seguem a mesma lógica do mercado web.

No mundo web, produtividade normalmente vence. No mundo embarcado, previsibilidade vence.

C continua sendo utilizado porque oferece algo que poucas linguagens modernas conseguem entregar com o mesmo nível de controle: domínio quase absoluto sobre hardware e memória. Quando um software precisa conversar diretamente com teclado matricial, módulo biométrico, firmware criptográfico, armazenamento interno e boot seguro, esse nível de proximidade importa muito.

O kernel Linux é escrito em C por esse motivo. Drivers são escritos em C por esse motivo. Firmware é escrito em C pelo mesmo motivo. Não é nostalgia tecnológica. É engenharia baseada em risco.

 

Onde o C++ entra nisso tudo

A parte interessante é que as urnas modernas não vivem apenas de C puro. As aplicações mais recentes utilizam bastante C++, principalmente junto do framework Qt.

E isso faz bastante sentido. O Qt é extremamente consolidado para interfaces gráficas em sistemas embarcados. Ele resolve renderização, gerenciamento visual, componentes gráficos e controle de interface com um nível de maturidade absurdo.

Quando o eleitor digita um número e a foto do candidato aparece instantaneamente, existe uma pilha inteira de software extremamente otimizada trabalhando ali.

A escolha do C++ acaba sendo um equilíbrio interessante: mantém performance, mantém controle fino sobre recursos, permite orientação a objetos, facilita organização do código e continua altamente auditável. Em sistemas desse tipo, auditabilidade vale ouro.

 

“Mas por que não usar Go?”

Essa pergunta ficou martelando na minha cabeça durante um tempo, principalmente porque Go é uma linguagem que eu gosto bastante. Ela resolve concorrência de forma elegante, compila binários estáticos, possui ótima performance e simplifica muita coisa que em C++ vira sofrimento.

Só que aí entra a diferença entre backend distribuído e sistema embarcado crítico.

Go possui Garbage Collector. E embora o GC do Go seja extremamente eficiente, ele ainda introduz pausas gerenciadas pela runtime. Em um backend isso normalmente é irrelevante. Em um equipamento de missão crítica, qualquer comportamento não determinístico pode virar problema. Mesmo pausas de poucos milissegundos podem ser consideradas indesejáveis.

Além disso, Go ainda não possui um ecossistema de GUI embarcada minimamente comparável ao Qt. Então a discussão deixa de ser “qual linguagem é mais moderna” e passa a ser “qual stack reduz mais risco operacional?”. São perguntas completamente diferentes.

 

O peso absurdo do legado auditado

Existe outro ponto que acho que muita gente subestima: o valor de código antigo que sobreviveu ao tempo.

Em desenvolvimento moderno existe quase um fetiche por reescrever tudo do zero. Só que software crítico não funciona assim. Cada eleição funciona como um ciclo gigantesco de validação prática.

O código das urnas já foi auditado por universidades, especialistas, partidos políticos, peritos independentes e órgãos diversos durante anos. Uma reescrita completa inevitavelmente criaria novos bugs. E software crítico odeia novidade.

No mercado tradicional a frase “move fast and break things” virou cultura. Em sistemas eleitorais, médicos, aeroespaciais e bancários, a lógica costuma ser praticamente o oposto: mover devagar e quebrar absolutamente nada.

 

O que mais me chamou atenção estudando isso

Talvez o ponto mais interessante seja perceber como engenharia muda completamente dependendo do contexto.

No backend moderno, eu provavelmente escolheria Go em muitos cenários sem pensar duas vezes. Mas quando o objetivo é criar um equipamento offline, determinístico, auditável, embarcado, criptograficamente validado e extremamente previsível, as prioridades mudam completamente.

E isso explica por que linguagens consideradas “antigas” continuam extremamente relevantes até hoje.

No fim, tecnologia não é sobre usar a stack mais nova. É sobre entender profundamente o problema que você está tentando resolver. E sistemas críticos costumam punir decisões tomadas apenas por hype tecnológico.

Compartilhe este post:
Voltar para a Home