Manhã: café, código e trocas de contexto
O relógio marca 9:15. Você abre o notebook, toma seu primeiro café e olha o Slack. 23 mensagens não lidas, três notificações de falhas de build e uma do líder técnico com um lacônico: "Veja o code review, tem seu bug em produção". Bom dia, desenvolvedor C++. Seu dia não começa com uma reunião, mas com um dump de memória e leitura de stack trace.
O dia de trabalho típico de um desenvolvedor C++ é um equilíbrio constante entre escrever código novo, depurar legado e comunicação. Diferente de Java ou Python, onde "simplesmente funciona" é um pouco mais comum, em C++ cada linha pode te prejudicar seis meses depois. Por isso, a manhã é hora de resolver os problemas de ontem.
Primeira ação: verificar CI/CD
Você abre o Jenkins (ou GitLab CI) — o build falhou. O linter passou, mas o compilador GCC 13 deu um erro críptico. Qual é o problema? Vamos ver:
// Exemplo: alguém esqueceu a semântica de movimentostd::vector<std::string> getNames() { std::vector<std::string> names = {"Alice", "Bob"}; return names; // NRVO funcionará, mas nem sempre}
// Isso não deve ser feito:std::vector<std::string> getNamesBad() { std::vector<std::string> names; names.push_back("Charlie"); return std::move(names); // Impede NRVO!}Você encontra e corrige. Envia o fix. CI fica verde. Dá para viver. Mas isso é só o começo.
Reunião matinal: por que o desenvolvedor C++ diz "é mais complicado do que parece"?
Às 10:00 — daily standup. Cada um conta o que fez ontem. Você diz: "Refatorei o módulo de processamento de imagens, reescrevi ponteiros brutos para inteligentes". Alguém dos juniores pergunta: "Por quê? Estava funcionando". Você suspira e explica que ponteiros brutos em C++ moderno é como andar em um campo minado sem mapa. O líder técnico acena. O junior anota no caderno: "Estudar RAII".
Nessa reunião, aliás, surge uma tarefa interessante para o desenvolvedor C++: reescrever um módulo antigo de void* para std::variant com segurança de tipos. Essa é a rotina típica — lidar com o legado do estilo C em um projeto C++.
Trabalho principal: código, bugs e magia de templates
Após a reunião, você mergulha na tarefa principal. Hoje é: implementar um novo algoritmo para parsing de configurações. Requisito: desempenho superior ao JSON e tipagem estrita. Você decide usar std::optional e std::expected (do C++23, mas disponível via Boost por enquanto).
Escrevendo código: parsing seguro
Você cria uma função que retorna std::optional<Config>. Se o parsing falhar — retorna std::nullopt. Sem exceções, sem nullptr, sem comportamento indefinido.
#include <optional>#include <string>#include <fstream>
struct Config { int port; std::string host; bool debug;};
std::optional<Config> parseConfig(const std::string& path) { std::ifstream file(path); if (!file.is_open()) { return std::nullopt; } Config cfg; file >> cfg.port >> cfg.host >> cfg.debug; if (file.fail()) { return std::nullopt; } return cfg;}
// Uso:auto config = parseConfig("app.cfg");if (config) { std::cout << "Porta: " << config->port << "";} else { std::cerr << "Falha ao analisar configuração";}Você verifica o código quanto a vazamentos de memória (valgrind), velocidade (perf) e correção (asan). Tudo limpo. Você faz commit. Mas não comemore cedo — em uma hora chegará uma mensagem do QA com um relatório de bug.
Almoço e conversas sobre Rust
Às 13:00 — almoço. No refeitório, os colegas discutem novidades: alguém está programando em Rust, outro está migrando para C++20. Você intervém: "E eu finalmente entendi std::jthread e cancellation tokens ontem". Ninguém entendeu