Domanda
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
Se avessi usato lo stile sopra come modello per dichiarare Macro, quali disposizioni avresti?
Soluzione
-
mette la parentesi attorno all'argomento (previene i problemi nel passaggio di espressioni)
-
non inserire; alla fine (l'uso sarà più naturale)
#define NULLCHECK (x) assert ((x)! = (void *) 0)
Altri suggerimenti
In generale, dovresti sempre mettere gli argomenti macro tra parentesi nell'espansione, cioè nel tuo caso
assert((x) != (void*) 0)
Questo perché, in caso contrario, eventuali espressioni (anziché semplici variabili) in cui si passa possono incasinare l'espansione della variabile.
Suggerirei anche di NON mettere il punto e virgola alla fine della definizione di macro, quindi devi chiamarlo come
NULLCHECK(pSomething);
che sembra più simile a C & amp; coerente con il resto del codice.
Una modifica che potrei fare sarebbe commentare il #endif
:
#endif // MACROS_NULLCHECK_H_
Rende più facile capire cosa ci fa #endif
quando il file diventa più lungo di uno schermo.
Alcune buone pratiche macro dal CERT C Wiki di codifica sicura :
PRE00-C. Preferisci le funzioni inline o statiche alle macro simili a funzioni
PRE01-C. Usa le parentesi nelle macro attorno ai nomi dei parametri
PRE02-C. Gli elenchi di sostituzione delle macro devono essere tra parentesi
PRE03-C. Preferisci i typedef da definire per i tipi di codifica
PRE10-C. Avvolgi macro multiistruzione in un ciclo do-while
PRE11-C. Non concludere una definizione di macro di una singola istruzione con un punto e virgola
PRE31-C. Non invocare mai una macro non sicura con argomenti contenenti assegnazione, incremento, decremento, accesso volatile o chiamata di funzione
PRE32-C. Non utilizzare le direttive del preprocessore all'interno degli argomenti macro
Sembra buono. È un modello che uso molto.
Per applicare il ;
, utilizzare
#define NULLCHECK(x) do { assert((X)); } while (0)