Я немного неохотно публикую этот ответ, потому что использование макро-хакерства может стать источником проблем. Однако - , если вызовы функции, которую вы хотите удалить, всегда используются отдельно в выражении (т. Е. Они никогда не являются частью большего выражения), тогда может сработать что-то вроде следующего (и это ручки varargs):
#ifdef SOMETHING
#define foo (1) ? ((void) 0) : (void)
#else
#define foo MyFunction
#endif
Итак, если у вас есть строка кода:
foo( "this is a %s - a++ is %d\n", "test", a++);
это закончится после шага предварительной обработки как:
MyFunction( "this is a %s - a++ is %d\n", "test", a++);
или
(1) ? ((void) 0) : (void)( "this is a %s - a++ is %d\n", "test", a++);
, который превращает список параметров псевдофункции в набор выражений, разделенных оператором запятой, который никогда не будет вычисляться, поскольку условное выражение всегда возвращает результат ((void) 0)
.
Вариант этого близок к тому, что предложили ChriSW и Джонатан Леффлер:
#ifdef SOMETHING
#define foo if (0) MyFunction
#else
#define foo if (1) MyFunction
#endif
Это немного отличается тем, что компилятору не требуется поддерживать переменные макросы (__VA_ARGS__
).
Я думаю, что это может быть полезно для устранения вызовов функций отладочной трассировки, которые обычно никогда не объединяются в большее выражение, но, кроме того, я думаю, что это опасный метод.
Обратите внимание на потенциальные проблемы - особенно если параметры в вызове вызывают побочные эффекты (это общая проблема с макросами, а не только этот хак). В этом примере a++
будет оцениваться, только если в сборке определено SOMETHING
, в противном случае это не так. Таким образом, если код после вызова зависит от значения a
, которое будет увеличено, в одной из сборок будет ошибка.