Linux elimina a API `strncpy` após seis anos de trabalho, 360 patches
Strings Terminadas em NUL vs Prefixadas por Comprimento / Tipos de String “Reais”
- Muitos argumentam que as strings C terminadas em NUL são uma das piores escolhas de design da computação: fáceis de transbordar, difíceis de raciocinar e armadilhas de desempenho (por exemplo, chamadas repetidas a
strlentransformando O(N) em O(N²)). - Outros observam que elas foram um compromisso pragmático em máquinas minúsculas dos anos 1970; sequências terminadas por sentinela (strings, arrays de ponteiros, listas encadeadas) eram baratas e combinavam com a prática em assembly.
- Strings no estilo Pascal ou prefixadas por comprimento evitam bugs de terminador ausente, mas trazem problemas: campos de comprimento de tamanho fixo (historicamente 255 caracteres), confusão entre bytes/codepoints/grafemas e dificuldade para fazer substrings sem copiar, a menos que você vá para “fat pointers” (ponteiro+comprimento).
- Variantes modernas discutidas:
struct { size_t length; T* ptr; }de D, BSTRs e cabeçalhos de Pascal/Delphi/Free Pascal, codificações dinâmicas/variáveis de comprimento, e tipos “span”/slice. Trade-offs: sobrecarga de memória vs velocidade vs slicing sem cópia.
NULL, NUL e Tipos Option
- A discussão distingue repetidamente NUL (byte terminador 0) de NULL (ponteiro inválido).
- Alguns veem NULL como algo aceitável e necessário; o problema real é não conseguir declarar ponteiros não nulos.
- Outros enfatizam os modernos tipos “option”/soma (por exemplo,
Option<T>) como a forma correta de representar valores “não definidos”, impostos pelo sistema de tipos em tempo de compilação. - Há debate sobre se ambientes de baixo nível podem ou devem substituir NULL por tais construções, ou usá-las como uma abstração de nível mais alto que se compila para representações com possibilidade de null.
Contexto Histórico e de Padrões
- Vários comentários destacam as origens do C: RAM minúscula (dezenas de KiB), compiladores de passagem única, limites de endereçamento do PDP-11 e reutilização de idioms já existentes. Nesse contexto, strings terminadas em null e o decay de ponteiro/array eram vistos como compromissos inteligentes, não erros.
- Propostas posteriores como fat pointers/slices e APIs mais seguras (por exemplo,
strlcpy) são citadas como oportunidades perdidas; criticam-se comitês por adicionar recursos complexos (VLAs,_Generic) enquanto mantiveram o modelo central de strings do C e a stdlib praticamente congelados.
strncpy, APIs do Kernel e Segurança
strncpyé descrita como amplamente mal utilizada e contraintuitiva: ela preenche com zeros, pode não terminar com NUL ao truncar e foi concebida originalmente para campos de tamanho fixo e preenchidos (por exemplo, antigas entradas de diretório), não como um “strcpyseguro”.- As funções substitutas do kernel (
strscpy,strscpy_pad,strtomem_pad,memcpy_and_pad,memcpy) codificam uma intenção mais clara (terminada ou não terminada, preenchimento vs cópia bruta), ao custo de mais APIs, mas com melhor segurança e sinalização de desempenho. - Alguns consideram essa proliferação “complicada”; outros argumentam que uma única ferramenta “canivete suíço” seria mais lenta e obscureceria a intenção.
IA e Refatoração Automatizada
- Uma linha de discussão pergunta se codificadores baseados em LLM poderiam ter automatizado a maior parte do trabalho de remoção de
strncpy. - Defensores relatam boas experiências usando LLMs para refatorar muitos programas em C e argumentam que seis anos é tempo demais para mudanças essencialmente mecânicas.
- Céticos respondem que, em um projeto do porte do kernel, os principais gargalos são revisão, coordenação e testes, não apenas edição; comportamentos sutis a jusante e a dependência de semânticas antigas precisam ser cuidadosamente auditados.
- Há uma fadiga visível com a IA sendo inserida em toda discussão de programação, junto com curiosidade sobre seu potencial para refatorações em grande escala.