Array in #define

I am trying to achieve something like this:

#define MACRO(x) {PORTB=0,PORTC=0,PORTD=0}

MACRO(0); //This would get replaced by PORTB=0;
MACRO(1); //PORTC=0;
MACRO(2); //PORTD=0;

      

I want to create an "array of macros". I would pass the index to it and return the correct code.

Is it possible?

EDIT:

If it helps, PORTB, PORTC and PORTD are #defines.

+3


source to share


2 answers


This can be done with a preprocessor, but it is arguably ugly.

#define MACRO_CASE0 PORTB = 0
#define MACRO_CASE1 PORTC = 0
#define MACRO_CASE2 PORTD = 0

#define MACRO(X) MACRO_CASE##X

      

Also check out the Boost.Preprocessor library . (It works for both C and C ++.)

Update: After discussion with Jonathan Leffler (see below). I feel a duty to update the answer with a call for new C programmers not to overuse the (powerful but dirty) method shown above.

If you, as requested by the OP, want to pass an index into it and it will return the correct code, then you need to resort to preprocessor programming. However, if all you want to do is execute other code based on some condition and doesn't require it to have no runtime overhead, if the condition is a compile-time constant, then the following approach is not only much cleaner, but and more flexible as it also allows you to pass runtime values.

/* '#include' this definition in any file where you want to use it. */
static inline void
do_the_right_thing(const int selector)
{
  switch (selector)
    {
   case 0:
      PORTB = 0;
      break;
   case 1:
      PORTC = 0;
      break;
   case 2:
      PORTD = 0;
      break;
   default:
      assert(!"cannot do the right thing: invalid selector");
    }
}

      



Now, in your code, if you write

do_the_right_thing(1);  /* selector is a compile-time constant */

      

a decent compiler with the appropriate optimizations enabled does not generate overhead compared to using a macro. However, you can also write

do_the_right_thing(rand() % 3);  /* selector is a run-time expression */

      

and the compiler inserts fast switch code to select the appropriate operation at runtime.

+5


source


This will do the job, but it won't expand or generalize very gracefully:



#define MACRO(x) (((x) == 0) ? PORTB=0 : ((x) == 1) ? PORTC=0 : PORTD=0)

      

+3


source







All Articles