#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
If I used the above style as a template for declaring Macros, what provisos would you have?
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
If I used the above style as a template for declaring Macros, what provisos would you have?
put parenthesis around the argument (it prevents problems when passing expressions)
don't put ; at the end (the use will be more natural)
#define NULLCHECK(x) assert((x) != (void*)0)
One change I might make would be to comment the closing #endif
:
#endif // MACROS_NULLCHECK_H_
It makes it easier to understand what that #endif
is doing there when the file gets longer than a screen.
Generally speaking, you should always put macro arguments in brackets in the expansion, i.e. in your case
assert((x) != (void*) 0)
This is because if you don't then any expressions (rather than simple variables) which you pass in may mess up the variable expansion.
I would also suggest that you DON'T put the semicolon at the end of the macro definition, so that you have to call it like
NULLCHECK(pSomething);
which just looks more C-like & consistent with the rest of your code.
Some good macro practices from the CERT C Secure Coding Wiki:
PRE00-C. Prefer inline or static functions to function-like macros
PRE01-C. Use parentheses within macros around parameter names
PRE02-C. Macro replacement lists should be parenthesized
PRE03-C. Prefer typedefs to defines for encoding types
PRE10-C. Wrap multi-statement macros in a do-while loop
PRE11-C. Do not conclude a single statement macro definition with a semicolon
PRE31-C. Never invoke an unsafe macro with arguments containing assignment, increment, decrement, volatile access, or function call
PRE32-C. Do not use preprocessor directives inside macro arguments
To enforce the ;
, use
#define NULLCHECK(x) do { assert((X)); } while (0)