Conditional compilation depending on function argument?

I searched around the world, and the information on the network seems to suggest that conditional compilation using a preprocessor works exclusively with environment variables.

Basically, I would like a built-in function or macro to perform different operations based on input arguments. An example of what I want to achieve:

inline void foo(int x) {

    #if (x < 32)

        register0 |= (1 << x);

    #else

        register1 |= (1 << (x - 32));

    #endif

}

The main goal here is that the resulting embedded code will not contain conditional code for persistent inputs.

, (lpc213x) . (, 0 1 ), , , .

, . , , , , , , .

,

Frob

+5
6

C:

#include <stdio.h>

volatile unsigned long register0 = 0, register1 = 0;

#define DEF0X(_X_) \
  static inline void SetPin##_X_() { register0 |= 1ul << _X_; }

#define DEF1X(_X_) \
  static inline void SetPin##_X_() { register1 |= 1ul << (_X_ - 32); }

DEF0X(0)  DEF0X(1)  DEF0X(2)  DEF0X(3)  DEF0X(4)
DEF0X(5)  DEF0X(6)  DEF0X(7)  DEF0X(8)  DEF0X(9)
DEF0X(10) DEF0X(11) DEF0X(12) DEF0X(13) DEF0X(14)
DEF0X(15) DEF0X(16) DEF0X(17) DEF0X(18) DEF0X(19)
DEF0X(20) DEF0X(21) DEF0X(22) DEF0X(23) DEF0X(24)
DEF0X(25) DEF0X(26) DEF0X(27) DEF0X(28) DEF0X(29)
DEF0X(30) DEF0X(31) DEF1X(32) DEF1X(33) DEF1X(34)
DEF1X(35) DEF1X(36) DEF1X(37) DEF1X(38) DEF1X(39)
DEF1X(40) DEF1X(41) DEF1X(42) DEF1X(43) DEF1X(44)
DEF1X(45) DEF1X(46) DEF1X(47) DEF1X(48) DEF1X(49)
DEF1X(50) DEF1X(51) DEF1X(52) DEF1X(53) DEF1X(54)
DEF1X(55) DEF1X(56) DEF1X(57) DEF1X(58) DEF1X(59)
DEF1X(60) DEF1X(61) DEF1X(62) DEF1X(63)

#define SET_PIN(_X_) SetPin##_X_()

int main(void)
{
  SET_PIN(0);
  SET_PIN(1);
  SET_PIN(32);
  SET_PIN(63);
  printf("register0=0x%08lX register1=0x%08lX\n",
         register0, register1);
  return 0;
}

:

register0=0x00000003 register1=0x80000001
+3

++ , :

template <bool B>
void doSetRegister(int x);

template<>
inline void doSetRegister<true>(int x) {
    register0 |= (1 << x);
}

template<>
inline void doSetRegister<false>(int x) {
    register1 |= (1 << (x - 32));
}

template <int X>
inline void setRegister() {
    doSetRegister<X <= 32>(X);
}

int main() {
    setRegister<1>();
    setRegister<33>();
}
+6

C, , , foo().

+2

, :

void foo(int x) {
  x < 32 && (register0 |= (1 << x));
  x >= 32 && (register1 |= (1 << (x - 32)));
}
+2

#define X 15 // or some else

#if X <= 32
#   define SET_X register0 |= (1 << X)
#else
#   define SET_X register1 |= (1 << (x - 32))
#endif
+1

C , , foo(), . , .

#define PIN_00  0x00000001, 0x00000000
#define PIN_01  0x00000002, 0x00000000
// defines left out here
#define PIN_31  0x80000000, 0x00000000
#define PIN_32  0x00000000, 0x00000001
// defines left out here
#define PIN_63  0x00000000, 0x80000000

inline void foo (unsigned long reg1, unsigned long reg2)
{
    register0 |= reg1;
    register1 |= reg2;
}

Then, to use this function foo(), you must specify an appropriate definition. Since a bitwise OR with a zero value does not change, the registers will be updated accordingly.

foo (PIN_00);
foo (PIN_01);
foo (PIN_32);
foo (PIN_63);

If you need to add a way to delete bits, you can create a new function using the same settings as below:

inline void fooRemove (unsigned long reg1, unsigned long reg2)
{
    register0 &= ~reg1;
    register1 &= ~reg2;
}
0
source

All Articles