bom, desconsiderando possiveis otimizacoes, eu acho que macros em excesso criam problemas logicos. por exemplo:
#define TRUE 1
#define FALSE 0
if(x==TRUE) true();
if(x==FALSE) false();
eh bem claro e definido, mas nao eh uma boa ideia, pois a linguagem C define 0 como false e qualquer outra coisa como true, nao apenas 1:
if(x) true();
else false();
por exemplo, no caso de contadores que decrementam a cada interacao, eh comum usar:
timer()
{
if(x) x--;
else timeout();
}
o que por si jah eh uma interpretacao muito mais vasta do que apenas TRUE e FALSE. no caso do contador, faria algo como if(x!=FALSE) ?
mas isso pode ser utilizado de outras formas. por exemplo, eh tipico as funcoes de biblioteca retornarem zero para sucesso e qualquer outra coisa para erros, permitindo codificar os erros:
if(ret = funcao()) error(ret);
novamente, if(ret != FALSE) seria bem estranho!
jah no aspecto de otimizacoes, existe uma possibilidade sim do codigo gerado ser diferente, pois limitar o resultado entre 0 e 1 eh bem diferente de limitar o resultado entre 0 e +/- 2^31. a armadilha aparece justamente na tentativa de compactar o booleano e consumir menos memoria, afinal para expressar TRUE e FALSE precisamos de apenas um unico bit! no caso de um bitstream de um bit, as operacoes logicas necessarias sao obvias.
seja d0 um o bit zero da variavel d, temos entao:
if(d.d0 == TRUE)
uma operacao que requer uma mascara. a armadilha de gastar menos memoria pode ter outros efeitos colateriais: usar um unsigned char melhora, mas pode nao ser suficiente em processadores RISC modernos que sao otimizados apenas para operandos de 32 bits. entao o menor numero de instrucoes e maxima otimizacao pode ser usar:
if(d)
onde d eh um int de 32 bits.
xultz escreveu:Mastk, uma coisa que é dificil de explicar prá programadores é que encolher o código-fonte em C não diminui o tamanho dele compilado.
Fazer
if (x=y+3) ...
dá exatamente no mesmo que
x = y+3;
if(x) ...
que dá exatamente no mesmo que
x = y + 3;
if (x == 0) ...
Das três, eu prefiro a última, porque fica mais evidente o que o código deve fazer. Uma vez um livro chamado Practical C e ele mostrava versões compiladas e mostrava que o resultado era idêntico.
Uma outra abordagem interessante eu li no livro do Jack Ganssle, onde ele teoriza que a função mais importante do código-fonte não é ser compilado e funcionar, mas é ser legível e que um humano possa ler e entender seu funcionamento. Gerar um executável dele é mera consequência. E essa cultura deve ser implantada na equipe.
Ele defende que a empresa tenha uma documentação que descreva estética de código e fluxo de trabalho. Por estética de código, compreende-se forma de indentação, nomenclatura de variáveis e funções, estilo de comentários e documentação. Por fluxo de trabalho, procedimento de repositório, revisão de código, testes, etc.
É um assunto complicaod: dá trabalho fazer isso, é impossível chegar um concenso (já tentei criar um padrão de biblioteca de componentes eletrônicos aqui e desisti), mas depois de implantado, dá retorno porque todo mundo fala a mesma língua.