0

I have two different macros that can get run depending on if the a define is set or not:

// Will do stuff later with the macroString
#define CASE_true(DEFINE, params) \
    auto macroString = std::to_string(DEFINE); \
    return true;

#define CASE_false(DEFINE, params) \
    return false;

What I want to be able to do is run CHOOSE_CASE macro with a define variable name and expand the respective function.

#define IS_DEFINED(x) IS_DEFINED2(x)
#define IS_DEFINED2(x) (#x[0] == 0 || (#x[0] >= '1' && #x[0] <= '9'))
    
#define CHOOSE_CASE(DEFINE, params) \
        CASE_##IS_DEFINED(DEFINE)##(DEFINE, params)

So if in my application somebody writes: #define MY_VAR 1, then CASE_ will expand the true case and get the value of MY_VAR, if MY_VAR is not set/defined, then CASE_ will expand the false case and not do anything with the define. Is this possible? The IS_DEFINED MACRO is probably not set up correctly but I don't know of any way to get it to work.

Moe Bataineh
  • 1,032
  • 1
  • 12
  • 29
  • Are you trying to do a string (character) comparison in your macro? That's not possible, especially not using c++ code. – πάντα ῥεῖ Jan 04 '21 at 20:08
  • The c preprocessoer only does text replacement (in a single pass). You can check the results with [calling only the preprocessing phase of the compiler](https://stackoverflow.com/questions/277258/how-do-i-see-a-c-c-source-file-after-preprocessing-in-visual-studio). – πάντα ῥεῖ Jan 04 '21 at 20:12
  • @πάνταῥεῖ: Macro replacement in C preprocessor does not do text replacement. It substitutes preprocessor tokens and evaluates the stringification and concatenation operators. – Eric Postpischil Jan 04 '21 at 20:33
  • @Eric OK, that's more precise, doesn't invalidate the fact that what the OP tries to do there isn't possible, since the condition cannot be evaluated by the preprocessor. – πάντα ῥεῖ Jan 04 '21 at 20:36
  • What you want is possible, but you must use a three-step macro: first the macro itself, then a step to stringize the actual definition value, then a step to look at that string. The last step must be in C or C++, not in the preprocessor, but with code optimization enabled, the dead branches should be eliminated. [See here](https://ideone.com/QCrxlP). (Just a comment, not an answer. I don't know what you want to achieve, but I think there must be better ways than macros, especially in C++.) – M Oehm Jan 04 '21 at 20:48
  • @MOehm, I'm trying to call the CASE_true or CASE_false depending on if the define exists. For example, if I tried to do `auto macroString = std::to_string(DEFINE);` with a DEFINE that does NOT exist, I will get compile errors. So I need the macro to unpack the appropriate function macro to call so I don't get any errors when giving it an invalid define. It's mainly for masking the to_string on a invalid case. – Moe Bataineh Jan 04 '21 at 21:20
  • Does it suffice to select based on whether `MY_VAR` is `1` or not, rather than whether it defined or not? – Eric Postpischil Jan 04 '21 at 21:49
  • This sort of stuff is much easier in C++ instead of C. Use templates and `if constexpr`. – MSalters Jan 05 '21 at 15:26
  • Yes, I think I understood. My code does what you tried to do in your code snippet. An undefined macro is not resolved or, I you will, it resolves to itself. Your macro definitions can only be numbers, so you check whether the first character of the string is a digit, only that you cannot do that last step in the preprocessor. Anyway, I'm still not convinced that a macro is the right solution here. – M Oehm Jan 05 '21 at 17:31

0 Answers0