18.06
2020
É comum programadores C/C++ com certa experiência não saberem como exatamente funciona o loop for. A maioria aprende um paralelo entre o For-To-Next e o for e não fica sabendo do verdadeiro poder do for em C/C++.
Veja o exemplo abaixo que valida a versão de um conjunto de nós:
for (ctnode = nnodes; ctnode--; )
if (strcmp(refversion, nodes[ctnode].version)
break;
if (ctnode >= 0)
TRACE(TRACE_ERROR, "Not all nodes in same version, aborting");
O código acima não contém nenhum erro. Mas contém uma construção um pouco controversa, um for não ortodoxo. Em algumas equipes de desenvolvimento esse tipo de construção é proibida, em outras amplamente utilizado. Não existe consenso, por mim, é válido e até mais rápido.
Mas um desenvolvedor C/C++ precisa entender como funciona um for.
Como Funciona?
O for em C/C++ é na verdade um while com inicialização e iteração embutidos. O for abaixo:
for (<INIT>; <COND>; <ITER>) {
<STATEMENTS>
}
É equivalente ao while:
<INIT>
while (<COND>) {
<STATEMENTS>
<ITER>
}
Vamos, então, refazer o for do trecho de código como se fosse um while:
ctnode = nnodes;
while (ctnode--) {
if (strcmp(refversion, nodes[ctnodes].version)
break;
}
Não podemos esquecer do incremento pós-fixado:
while (ctnode--)
Executa a seguinte sequência:
1. verifica se ctnode é zero, se for sai do loop
2. decrementa o valor de ctnode
Dessa forma na primeira passada do loop o valor de ctnode não é nnodes, o que causaria um index out-of-bounds, mas sim nnodes – 1, o que indexa corretamente o último valor do array. E a última passada a condição resolve como 1, mas dentro do loop como 0. E em caso de sucesso o valor de ctnodes é -1.
E o break?
O break, e o if após o loop, é o que torna essa construção ainda mais interessante. Quando o loop é interrompido o contador não chegou a zero. Portanto detecta-se a interrupção através de um teste no contador, se o contador não for negativo, sucesso.
E pra finalizar o valor em ctnode após o loop contém o índice do node que que está com versão errada.
E Ainda Tem a Performance
Em sistemas embarcados aonde qualquer tipo de otimização conta, utilizar a construção proposta aumenta a performance, pois a saída do loop é feita com uma condição que testa zero, muito mais rápida para qualquer processador, e depois a verificação de erro é também testada com um teste de zero. Portanto a solução tem mais performance que a mais ortodoxa.
Quando Não Usar?
Por que algumas pessoas não recomendam a construção não ortodoxa do for? Essa construção é bem típica da linguagem C/C++, e é completamente não ortodoxa, muitos programadores não entendem como de fato funciona o for, e ao encontrar tal solução não conseguem interpretá-lo de maneira correta.
Se na sua base de desenvolvedores houver muitos programadores pouco experientes, ou com conhecimento superficial de C/C++ é melhor não utilizar a construção. Afinal tão importante quanto a performance da aplicação é a performance da manutenção.
Comentários
[…] a construção não ortodoxa do for para determinar se a entrada é numérica ou não. Para maiores informações veja neste post. […]
[…] Já discutimos várias construções desse tipo de for no Lab C++ antes. […]