1
votes

I tried the following syntax to define a macro:

#define SETBIT(ADDRESS,BIT,NEG)  #if NEG                    \
                                   (ADDRESS &= ~(1<<BIT))   \
                                 #else                      \
                                   (ADDRESS |= (1<<BIT))    \
                                 #endif

Using:

#define LED1 PORTA,1,1   \\ LED with anode to Vcc
#define LED2 PORTA,1,0   \\ LED with anode to GND
SETBIT(LED1)             \\ resulting in bit clear
SETBIT(LED2)             \\ resulting in bit set

I hope that the main point is clear: I'd like to specify the port polarity only in one place and make the code more readable and scalable.

However GCC compiler complains for it:

ipt.h:1: error: '#' is not followed by a macro parameter (column 30)

I found out that #if is not allowed within a macro definition.

How am I able to declare the macro with indicated function?

1
do{ if(NEG) (ADDRESS &= ~(1<<<BIT)); else (ADDRESS |= (1<<BIT));}while(0) - BLUEPIXY
@BLUEPIXY Could you make clear why you're using do-while loop here? - Roman Matveev
Roman, you seem to have misunderstood preprocessor directives. Those things that start off with a # are issued, before even your programme is compiled, so definitely before a variable like NEG means anything. While using #if, you either have to use an integer constant like 1 or 0, for true and false, respectively; or a macro definition like #define ASD 1, and use the ASD in place of 1, and so on... - Utkan Gezer
E.g if(condition)SETBIT(PORTA,1,1);else otherthing; is prevented so as not to cause this error. - BLUEPIXY
What @BLUEPIXY means is that macros are inserted into existing code as replacement text without regard for meaning. The example he gives will get messed up by creating two ifs followed by two elses. The do {} while(0) trick makes sure that your macro is inside braces, but also allows it to be inserted as a statement. It can go anywhere without messing up existing code. The trick works because the "loop" will be executed exactly once. - uncleO

1 Answers

2
votes

Try something like this:

#define SETBIT(ADDRESS,BIT,NEG) \
  if (NEG)                      \
    (ADDRESS &= ~(1<<BIT));     \
  else                          \
    (ADDRESS |= (1<<BIT));