Ebony Ayers
Ebony Ayers

Reputation: 360

How to tell if a #define has a value or not

As I understand with the C preprocessor you can use #define in one of two ways:

  1. #define SOME_VAL 3.4159f
  2. #define SOME_FLAG

I am writing a library and I am using #defines to for the user to parse in settings to do with compilation. My problem is I need to know which of the two aforementioned cases has been used.

Example: #define DISABLE_FEATURE or #define DISABLE_FEATURE false.

Is there a way for me to distinguish these two or do I have to specify in documentation which to use?

Upvotes: 2

Views: 1588

Answers (2)

eerorika
eerorika

Reputation: 238351

do I have to specify in documentation which to use?

Technically no, you don't. But you should.

You can easily normalise on checking for false by doing this:

#ifndef DISABLE_FEATURE
#define DISABLE_FEATURE false
#endif

// later
#if DISABLE_FEATURE == false
...

Normalising on checking for definedness is a bit trickier because you cannot compare an empty macro with a value. But it is possible. You can use macro magic such as this (expansion magic borrowed from here):

#define DO_EXPAND(VAL)  VAL ## 1
#define EXPAND(VAL)     DO_EXPAND(VAL)

#if defined(DISABLE_FEATURE) \
    && (EXPAND(DISABLE_FEATURE) == false)
#undef DISABLE_FEATURE
#endif

// later
#ifdef DISABLE_FEATURE
...

I recommend instead to stick to one way and to document that. In particular I recommend checking for definedness, and to ignore the value entirely.

Upvotes: 5

Some programmer dude
Some programmer dude

Reputation: 409176

You can check if a macro exists with e.g.

#if defined(SOME_FLAG)
...
#endif

See e.g. this macro conditional reference.


With that said, it's impossible to distinguish between an "empty" macro (like SOME_FLAG in your example) and a macro defined with the integer literal 0 as the replacemenent.

Also note that unless the macro can be evaluated by the preprocessor you can't compare its "value".

For something like DISABLE_FEATURE you can do something like

#if defined(DISABLE_FEATURE) || DISABLE_FEATURE != false
    // Feature *is* disabled
#else
    // Feature is not disabled
#endif

Upvotes: 0

Related Questions