The classic way to do this would be:
foo.h
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED
#if SOME_CHECK
extern void foo(int x, int y, int z);
#define FOO(x, y, z) foo(x, y, z)
#else
#define FOO(x, y, z) ((void)0)
#endif
#endif /* FOO_H_INCLUDED */
Code conditionally calling foo()
#include "foo.h"
...
FOO(a, b, c);
...
When SOME_CHECK is defined to a non-zero value, then the code will call foo()
with the given arguments. When SOME_CHECK is not defined, the code will expand to ((void)0)
which will be ignored by the compiler.
You probably can leave the alternative definition as an empty string if you wish (instead of using ((void)0)
, but you'd run into problems if someone tried to use FOO()
in the context of a comma operator, or a ternary operator, for example:
FOO(a, b, c), ALTEREGO(d, e f);
(x > y) ? FOO(a, b, c) : ALTEREGO(d, e, f);
In both of those, #define FOO(x, y, z) /* Nothing */
would generate syntax errors. This is not the end of the world; they're both horrid bits of code and shouldn't be encouraged. But that's a judgement call you'll have to make for your project.