У меня есть следующие строки кода, которые необходимо написать во многих файлах в проекте:
#if SOME_CHECK
foo(x, y, z);
#endif
Для этого я планирую обернуть вышеуказанные 3 строки кода в один макрос, например this-
#define foo(x, y, z) #if SOME_CHECK \
foo(x, y, z); \
#endif
Но это дает мне ошибку по понятным причинам, и я не могу придумать, как лучше использовать макросы препроцессора, чтобы обернуть эти 3 строки кода. Может ли кто-нибудь предложить несколько лучших способов справиться с вышеуказанной проблемой?
Классический способ сделать это:
#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 */
foo()
#include "foo.h"
...
FOO(a, b, c);
...
Когда SOME_CHECK определяется ненулевым значением, код будет вызывать foo()
с данными аргументами. Когда SOME_CHECK не определен, код будет расширяться до ((void)0)
который будет проигнорирован компилятором.
Вероятно, вы можете оставить альтернативное определение пустой строкой, если хотите (вместо использования ((void)0)
, но у вас возникнут проблемы, если кто-то попытается использовать FOO()
в контексте оператора запятой или тройной оператор, например:
FOO(a, b, c), ALTEREGO(d, e f);
(x > y) ? FOO(a, b, c) : ALTEREGO(d, e, f);
В обоих случаях #define FOO(x, y, z)/* Nothing */
генерирует синтаксические ошибки. Это не конец света; они оба ужасные части кода, и их не следует поощрять. Но это решение, которое вы должны будете сделать для своего проекта.
Почему бы не сделать это?
#if SOME_CHECK
... The actual function
#else
#define foo(x,y,z)
#endif
Если любое вхождение foo
будет SOME_CHECK
тогда будет установлен SOME_CHECK
. В противном случае вызывается функция.
SOME_CHECK
не равен нулю, не так ли?
как насчет попытки:
#ifdef SOME_CHECK
#define foo(x,y,z) foo(x,y,z);
#else
#define foo(x,y,z)
#endif