-2
#define STRIP0 0
#define STRIP1 1
#define STRIP2 2
#define STRIP3 3
#define  PINS0 2,3,4
#define  PINS1 5,6,7
#define  PINS2 8,9,10
#define  PINS3 11,12,13

#define PINS(STRIP) { (STRIP) == (STRIP0) ? PINS0 :\
                      (STRIP) == (STRIP1) ? PINS1 :\
                      (STRIP) == (STRIP2) ? PINS2 :PINS3}

now if when i call a function that takes 3 arguments all of type int foo(int,int,int); like this foo(PINS1); then the function compiles and works as expected(all arguments are passed as if the #define was replaced by "5,6,7")

but if i use the macro for selecting the set of pins like foo(PINS(STRIP1)); then the argument selection goes haywire. in this specific case the faulty argument list becomes "7,12,13" and for foo(PINS(STRIP0)); it becomes "4,12,13" there is a pattern that i see but i dont have the expertise to tell and rectify what is happening at compile time.

  • If you use the `PINS` function-like macro you have two problems: The first is the curly-braces you have around the whole expression, The second is that instead of passing multiple arguments you pass a single argument because then the comma becomes nor an argument separator but the comma expression. You should reconsider your use of macros, any maybe use an `inline` function wrapper instead? Or at least modify the macro, maybe to take the function as an argument and have the call inside the macro "body"? – Some programmer dude Oct 30 '16 at 06:25
  • Why don't you just write an `if/else` – Danh Oct 30 '16 at 06:27
  • @Someprogrammerdude i will remove the curly braces and edit the question but it had no effect in the output. when i do this `foo(PINS1);` (as specified in the question) the function takes the 3 numbers as arguments itself which led me to believe that the comma as expression wasnt happening instead compiler recognized that there are 3 arguments and that is why it proceeded. this is the reason that i thought doing a macro that selects the `PINS0` or `PINS1` will work but it didnt. your suggestion to have the function as an argument in the macro is probably what krzaq is suggesting – Pranav Gulati Oct 30 '16 at 08:00

1 Answers1

0

Imo you're hurting readability a lot by using macros for this. But here's how I'd do this:

#define STRIP0 0
#define STRIP1 1
#define STRIP2 2
#define STRIP3 3
#define  PINS0 2,3,4
#define  PINS1 5,6,7
#define  PINS2 8,9,10
#define  PINS3 11,12,13

#define CONCAT_HELP(A, B) A ## B

#define CONCAT(A, B) CONCAT_HELP(A, B)

#define PINS(FUNC,STRIP) FUNC(CONCAT(PINS, STRIP))

now, you'd call this like this:

PINS(foo, STRIP0);

demo

You need two levels of indirection, because of the way macro replacement works (here is an in-depth explanation). With just #define CONCAT(A,B) A ## B, CONCAT(PINS,STRIP0) would create PINSSTRIP0 which makes no sense here.


For completeness sake, if you expect to use this with runtime values (of which you gave no indication of in the question), you could go with a helper function template that would switch over the strip value:

template<typename Func>
void pins(Func f, int strip)
{
    switch(strip){
    case 0: f(PINS0); break;
    case 1: f(PINS1); break;
    case 2: f(PINS2); break;
    case 3: f(PINS3); break;
    }
}

demo

and, if you have C++17 available:

constexpr tuple<int,int,int> params[] = {
    make_tuple(PINS0),
    make_tuple(PINS1),
    make_tuple(PINS2),
    make_tuple(PINS3)
};

template<typename Func>
void pins(Func f, int strip)
{
    apply(f, params[strip]);
}

demo

though at this point, the helper function stops being necessary.

Community
  • 1
  • 1
krzaq
  • 16,240
  • 4
  • 46
  • 61
  • 1
    I definitely needed my coffee. Good answer, but maybe it's pertinent to explain *why* an intermediate expansion is required. The OP doesn't seem to be well versed. – StoryTeller - Unslander Monica Oct 30 '16 at 06:29
  • @StoryTeller added. – krzaq Oct 30 '16 at 06:56
  • 1
    the objective that i'm trying to accomplish is that each PINS0 set corresponds to a different set of physical pin connections that do not change at runtime and need to be passed as arguments to various functions so by doing something like this i will save the trouble of changing these definitions everywhere thats all! i'll try your answer looks like it should work @StoryTeller i am not very well versed for sure thanks everyone for their help ;-) – Pranav Gulati Oct 30 '16 at 07:34