Question

#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?

Was it helpful?

Solution

  • 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)

OTHER TIPS

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.

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.

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

Looks good. It's a pattern I use a lot.

To enforce the ; , use

#define NULLCHECK(x) do { assert((X)); } while (0)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top