6

Consider the following simple C/C++ example:

#define FOO
...
#ifdef FOO
  bar++;
#endif

OK, now I would like to fit that (and any other similar) conditional into one line for the code readability sake (the code has tens of single-line statements that all need to be conditional each depending on different define). Something that, when used, would look like:

#define FOO
...
MY_IFDEF(FOO,bar++;) //Single-line conditional

The goal is to have a reusable macro that can take an arbitrary identifier and, compile the statement if such identifier has been #define-d previously, and do it all in a single line.

Any ideas?

UPDATE0: the code must compile for both C and C++

4
  • 2
    I don't think you can have a macro expand to #ifdefs; the expansion isn't scanned for conditionals. Commented Jun 12, 2021 at 18:14
  • you can make function and match macro's corresponding value in if condition and do whatever you want if comes true Commented Jun 12, 2021 at 18:23
  • Do not tag both C and C++ except when asking about differences or interactions between the languages. If you want answers for both languages, you can ask separate questions. Pick one tag and delete the other. Commented Jun 12, 2021 at 19:26
  • looks like you dont know about #undef Commented Jun 13, 2021 at 0:43

2 Answers 2

4

You can't use #ifdef while expanding macros, but you can totally precheck it and declare empty statement if condition is not met.

#ifdef FOO
  #define MY_IFDEF(x,y) some-processing-you-need
#else
  #define MY_IFDEF(x,y) ;
#endif

Also check out new feature of C++: constexpr this can also be usable.

2
  • This solution does not work with arbitrary identifiers and require pre-defining similar sections for each identifier (which are not necessarily known to me upfront). "x" in MY_IFDEF was exactly an argument for such identifier. Commented Jun 13, 2021 at 12:41
  • @RegusPregus yes, as mentioned in other answer you should use constexpr or if for single-line definition.
    – Alex
    Commented Jun 13, 2021 at 12:54
2

UPDATE4: As pointed out by @Alex Bakanov you can't use #ifdef while expanding macros, so there is no single line solution for your question which works in all cases. Nevertheless, I hope the idea I wrote here may be useful.

if you use #define FOO 1 or #define FOO 0, combination of #define and if constexpr can be used. Note that it gives an error if FOO is not defined. This program gives 1 as result:

#include<iostream>

#define FOO 1
#define MY_IFDEF(x,y) if constexpr (x) y;

int main()
{
    int bar =0;
    MY_IFDEF(FOO,bar++)

    std::cout << bar << "\n";  
}

UPDATE: Based on @eerorika's comment to avoid the error if FOO is not defined, the following declaration has to be added:

constexpr bool FOO = false;

UPDATE2: This version works in any circumstances, the only question is that is it worth the effort?

#ifdef FOO
    constexpr bool USED_FOO = true;
#else
    constexpr bool USED_FOO = false;
#endif

#define MY_IFDEF(x,y) if constexpr (USED_##x) y ;

UPDATE3: C compatible version. Note that in this case in theory it is evaluated runtime not compile time, but the compiler will realize that it is always true/false and generates the code accordingly:

#ifdef FOO
    const static bool USED_FOO = true;
#else
    const static bool USED_FOO = false;
#endif

#define MY_IFDEF(x,y) if (USED_##x) y;
12
  • Good suggestion. Similar can work without needing #define FOO 0 by using a constexpr bool variable.
    – eerorika
    Commented Jun 12, 2021 at 19:26
  • @eerorika What do you mean? MY_IFDEF(FOO,bar++) always gives an error if FOO is not defined.
    – Laci
    Commented Jun 12, 2021 at 19:33
  • That error is what you can avoid by using a variable.
    – eerorika
    Commented Jun 12, 2021 at 19:41
  • OK, You are right, but it cannot be defined as a compiler option
    – Laci
    Commented Jun 12, 2021 at 19:43
  • 1
    The point is to define the variable unconditionally, and choose the value based on whether the macro is defined or not.
    – eerorika
    Commented Jun 12, 2021 at 19:46

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