2016-05-19 4 views
0

У меня есть файл конфигурации с большим количеством определений, которые используются для включения модулей во время выполнения. Кроме того, это означает, что я должен проверить очень многое внутри кода для определения. Для каждой проверки требуется 3 строки, это возможно сделать в одной строке.Один оператор строки #if

#if FUNC_ENABLED 
function_optional_call(); 
#endif 

Я ищу что-то вроде.

CALL(function_optional_call(),FUNC_ENABLED); 

Есть ли способ сделать это, или мне нужно использовать выражение 3 строки. Я знаю, что он может определить макро для каждого макро.

Skip function call if not defined

Но можно ли сгенерировать Generall Makro.

+0

Какой компилятор и версия вы используете? поскольку это предпроцессорная вещь, я сомневаюсь, что есть общий способ сделать это, и вам придётся прибегнуть к некоторым трюкам. – Neil

+0

Большинство компиляторов C, которые я использовал (еще в 90-х годах), не разрешали #if в #define (следовательно, проблема у вас есть). Если вы не можете использовать boost (согласно другому ответу), который является библиотекой C++, тогда он вряд ли будет легко разрешимым. – Neil

ответ

0

Это довольно легко с помощью Boost.PP, в том, что это именно то, что делает BOOST_PP_IF:

#include <boost/preprocessor/if.hpp> 

#define CALL(expr, cond) \ 
    BOOST_PP_IF(cond, expr,) 

Каждое использование CALL расширяется до expr или ничего, в зависимости от значения cond.

Live on Coliru

+0

Это именно то, что я искал, но это швы, чтобы быть заголовком C++ – Schafwolle

+0

@Schafwolle Это не так. Boost.Preprocessor - это библиотека полиглота C/C++ и работает с обоими. Обратите внимание, что живой пример * * скомпилирован как C через флаг '-x c'. – Quentin

+0

@Quention Thx Понятно, что CALL был просто фиктивным именем, поэтому я собираюсь напрямую использовать boost makro вместо – Schafwolle

4
#if FUNC_ENABLED 
function_optional_call(); 
#endif 

- канонический способ написания переключателя компилятора. Понятно, что это понятно, каждый программист понимает, что он делает.

Сейчас этот код:

CALL(function_optional_call(),FUNC_ENABLED); 

совершенно таинственное. Непонятно, для чего это, почему существуют макросы ... это даже не похоже на действительный C.

Таким образом, первая форма намного превосходит последнюю, что является просто уродливой, плохой практикой. Поэтому не пытайтесь переписать первое в последнее.


Если вы беспокоитесь о повторении той же линии снова и снова, он предпочел бы, кажется, что эта проблема является неправильное расположение переключателя компилятора. Поместите его внутрь функции. Или, если вы не можете изменить функцию, сделайте обертку.

+0

Ну, честно говоря, первый тоже нехорошо. Условную компиляцию компиляции не следует разрешать, защищая каждое использование с помощью препроцессора. Он просто создаст нечитаемый код. Источником Vim является один хороший пример, который приходит на ум, он имеет «# if», посыпанный всей кодовой базой. – Leandros

1

Ранее, имеют:

#if FUNC_ENABLED 
# define func_optional() real_func_name() 
#else 
# define func_optional() 
#endif 

Вы можете использовать некоторые приемы во втором случае, чтобы избежать проблем, связанных с точкой с запятой, например, do {} while (0).

Смежные вопросы