4

I have a config file with a lot of defines that are used to include modules during the complie time. In addition this means that I have to check very oft inside of the code for defines. Every check requires 3 lines is it possible to do this in one line.

#if FUNC_ENABLED
function_optional_call();
#endif

I'm looking for something like.

CALL(function_optional_call(),FUNC_ENABLED);

Is there a makro possible doing this or do I have to use the 3 line expression. I know its possbile to define a makro for every makro.

Skip function call if not defined

But is it possible to generate a generall makro.

2
  • Which compiler and version are you using? as this is a pre-processor specific thing, I doubt there is a generic way of doing it and you'll have to resort to some tricks.
    – Neil
    Commented May 19, 2016 at 10:27
  • Most of the C compilers I used (back in the 90s) didn't allow #if within a #define (hence the problem you are having). Unless you can use boost (as per the other answer), which is a C++ library, then it's unlikely to be easily solvable.
    – Neil
    Commented May 19, 2016 at 10:30

3 Answers 3

4
#if FUNC_ENABLED
function_optional_call();
#endif

is a canonical way of writing a compiler switch. It is clear, it is readable, every programmer understand what it does.

Now this code:

CALL(function_optional_call(),FUNC_ENABLED);

is completely mysterious. It is not clear what it is for, why there are macros... it doesn't even look like valid C.

Thus the first form is far superior, to the latter, which is just ugly, bad practice. So don't try to re-write the former into the latter.


If you worry about repeating the same line over and over, it would rather seem that the problem is an incorrect placement of the compiler switch. Put it inside the function instead. Or if you can't modify the function, make a wrapper.

1
  • Well, to be honest, the first one is not good either. Conditional compilation compilation should not be resolved by guarding every single usage with a preprocessor guard. It'll just create unreadable code. The Vim source is one good example which comes to mind, it has #if sprinkled over the whole codebase.
    – Leandros
    Commented May 19, 2016 at 12:43
2

It's pretty easy with the help of Boost.PP, in fact that's exactly what BOOST_PP_IF does:

#include <boost/preprocessor/if.hpp>

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

Every use of CALL expands to expr or nothing, depending on the value of cond.

Live on Coliru

3
  • This is exactly what I have looked for but it seams to be a C++ header
    – Schafwolle
    Commented May 19, 2016 at 10:02
  • @Schafwolle It's not. Boost.Preprocessor is a C/C++ polyglot library, and works with both. Note that the live example is compiled as C via the -x c flag.
    – Quentin
    Commented May 19, 2016 at 11:24
  • @Quention Thx By the way of course the CALL was just a dummy name so I'm going to directly us the boost makro instead
    – Schafwolle
    Commented May 19, 2016 at 11:35
1

Earlier on, have:

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

You could use some tricks in the second case to avoid problems caused by the semicolon, e.g. do {} while (0).

Not the answer you're looking for? Browse other questions tagged or ask your own question.