Pergunta
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
Se eu usasse o estilo acima como modelo para declarar macros, quais ressalvas você teria?
Solução
Coloque parêntese em torno do argumento (evita problemas ao passar expressões)
Não coloque; no final (o uso será mais natural)
#Define NullCheck (x) Assert ((x)! = (void*) 0)
Outras dicas
De modo geral, você deve sempre colocar argumentos macro entre colchetes na expansão, ou seja,no seu caso
assert((x) != (void*) 0)
Isso ocorre porque, se você não fizer isso, quaisquer expressões (em vez de variáveis simples) que você passar poderão atrapalhar a expansão da variável.
Eu também sugeriria que você NÃO coloque ponto e vírgula no final da definição da macro, para que você tenha que chamá-la como
NULLCHECK(pSomething);
que parece mais parecido com C e consistente com o resto do seu código.
Uma mudança que eu poderia fazer seria comentar o fechamento #endif
:
#endif // MACROS_NULLCHECK_H_
Torna mais fácil entender o que isso #endif
está fazendo lá quando o arquivo fica mais longo que uma tela.
Algumas boas macro práticas do Cert C Wiki de codificação segura:
Pre00-C. Prefira funções embutidas ou estáticas a macros do tipo função
Pré01-c. Use parênteses em macros em torno dos nomes de parâmetros
Pré02-c. As listas de substituição de macro devem ser entre parênteses
Pré03-c. Prefere typedefs a definir para os tipos de codificação
Pre10-c. Enrole as macros de várias estaturas em um loop de doen
Pre11-c. Não conclua uma única definição de macro de declaração com um semicolon
Pre31-c. Nunca invoca uma macro insegura com argumentos contendo atribuição, incremento, decréscimo, acesso volátil ou chamada de função
Pre32-c. Não use diretrizes de pré -processador dentro de argumentos macro
Parece bom. É um padrão que eu uso muito.
Para fazer cumprir o ;
, usar
#define NULLCHECK(x) do { assert((X)); } while (0)