5

Let's say I have 2 sets of values for P_A, P_B, P_C as below

#define X_P_A  2
#define X_P_B  3
#define X_P_C  4

#define Y_P_A  5
#define Y_P_B  6
#define Y_P_C  7

There are 3 types of users:- once that only need X variants, once that only need Y variants and once those may need both.

eg

#ifdef X
    #define P_A  X_P_A
    #define P_B  X_P_B
    #define P_C  X_P_C
#endif

#ifdef Y
    #define P_A  Y_P_A
    #define P_B  Y_P_B
    #define P_C  Y_P_C
#endif

Users that need both will make the decision at run time and call X_P_<> or Y_P_<> as needed.

Is there a way to make it simpler, so that I don't have to write conditional macros for each field

ifdef X
// do something magical does defines all P_<> to X_P_<>
#endif

I know it sounds stupid. You may ask why not just use X_P_<> variants on X. I am just trying to understand if it is possible.

I am okay with changing the way the macros the defined. Is something similar to below code possible : (problem with below code is that compilation fails because #if not allowed within #define)

#define A 1
#define B 2
#define C 3

/* Not a correct #define macro */    
#define X_P(x)    \
#if(x == A)    2  \  
#elif(x == B) 3  \ 
#elif(x == C)  4  \
#endif

#ifdef X
 #define P(x) X_P(x)
#endif
3
  • Why do you think you need macro's to do this? Isn't a(n inline) function a lot clearer and less error-prone? Commented May 11, 2018 at 12:22
  • 1
    You can't use #if inside a macro definition. You can't use enum constants in pre-processor conditional tests either, but you can replace those with macros. Some of your other syntax is also invalid, e.g. #ifdef(X) should be #ifdef X or #if defined(X). Commented May 11, 2018 at 12:28
  • Thanks, fixed some errors in syntax Commented May 11, 2018 at 12:44

2 Answers 2

2

You could do it with one variant of X-Macros:

#define IMPLEMENT(X) \
    X(P_A, 1, 5) \
    X(P_B, 2, 6) \
    X(P_C, 3, 7)

enum {
    // Just one
    #define X1_P(n, x, y) n = x,
    IMPLEMENT(X1_P)

    // Both
    #define X2_P(n, x, y) X_##n = x,
    #define Y2_P(n, x, y) Y_##n = y,
    IMPLEMENT(X2_P)
    IMPLEMENT(Y2_P)

    DUMMY // Just in case compiler is strict about trailing comma
};

Which would expand to:

enum {
    P_A = 1, P_B = 2, P_C = 3,

    X_P_A = 1, X_P_B = 2, X_P_C = 3,
    Y_P_A = 5, Y_P_B = 6, Y_P_C = 7,

    DUMMY
};
Sign up to request clarification or add additional context in comments.

Comments

1
#define X_P(x)  ((x) - 0x10 + 1) // 1 is 0x31 and A is 0x41 hence A will give 0x41 - 0x10 + 1 = 0x32
#define Y_P(y)  ((y) - 0x10 + 5) // same logic applies

Would it be what you are looking for ? Not fully answering your question though

2 Comments

Don't forget to add brackets around x and y, as well as the whole expression being defined.
Sorry, the values I gave were just example. They don't really follow any pattern

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.