Este post vem, justamente lhe dizer para parar de fazer isso. Diremos o porquê não usar essa macro nos seus programas futuros e também quando você deve usar - se for preciso.
Em resumo esse post quer dizer: prefira o compilador ao pré-processador.
Considere: #define F 6.666
Então todas as evidencias de F serão retiradas e substituidas por 6.666, antes antes do código ser efetivamente compilado pelo compilador, pelo pré-processador. Portanto 'F' não entrará na tabela de símbolos.
Isso pode ser confuso num momento posterior. Afinal, o compilador pode apontar erros na parte do código em que anteriormente encontráva-se o símbolo 'F'. Contudo, o erro apontado será para o '6.666' pois é ele que está no código que o compilador está tentando compilar.
Se você tem essa macro ('F') num arquivo separado, onde, talvez, você e/ou o usuário futuro nem ao menos tenham acesso, será muito difícil encontrar o erro apontado pelo compilador.
Prefira: const double F = 6.666;
Isso deve corrigir o problema acima descrito. E ganhamos ainda um benefício extra: O código será menor.
Por quê?
Porque com o #define temos possivelmente multiplas cópias de 6.666 por todo o código, enquanto com a constante teremos certamente apenas uma cópia.
Constantes dentro de classes.
Se a constante estiver dentro de um scopo de uma classe toda, então você deve declará-la como statica, para evitar multiplas cópias desnecessárias.
Em algum momento dentro de classes, na declaração de arrays com tamanho constante, talvez precise de um hack. Isso porque o compilador pode 'sismar' em querer saber, logo na classe, o tamanho do array, para tanto podemos usar o enum hack. Simples, declare um enum na classe que inicia no tamanho que você deseja e use-o como constante.
Não use #define para função.
Considere: #define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))
Por que não usar?
imagine que, com a = 5 e b = 0, você chame:
CALL_WITH_MAX(++a, b); // a é incrementado duas vezes
CALL_WITH_MAX(++a, b+10); // a é incrementado apenas uma vez
Podemos juntar a eficiência das macros mais o comportamento prático e a segurança de tipagem de uma função regular usando Templates para uma função inline.
template
inline void callWithMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
(Note a constante para refencia. Abordamos isso e outras coisas semelhantes em um outro poste).
Com consts, enums e inlines você reduz a necessidade do preprocessador (especialmente #defines), mas não elimina. #include, por exemplo é essencial, e #ifndef e #ifndef que continuam a ser importante no controle da compilação. Também para códigos legados que usavam #defines e etc.
Lembre-se:
* prefira objetos consts ou enums à #defines.
* para funções do tipo macro, prefira função inline à #defines.
Referencia:
Effective C++ Third Edition 55 Specific Ways to Improve Your Programs and Designs By Scott Meyers
Nenhum comentário:
Postar um comentário