条件编译取决于函数参数?

FRo*_*Rob 5 c c-preprocessor

我搜索的范围很广,网上的信息似乎暗示使用预处理器的条件编译仅适用于环境变量.

基本上,我希望内联函数或宏基于其输入参数执行不同的操作.我想要实现的例子:

inline void foo(int x) {

    #if (x < 32)

        register0 |= (1 << x);

    #else

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

    #endif

}
Run Code Online (Sandbox Code Playgroud)

这里的主要目标是生成的内联代码不包含常量输入的条件代码.

基本上,我目前正在为一个微控制器(lpc213x)编程,并希望有一个内联函数或宏来进行引脚配置设置.由于引脚配置分为多个寄存器(例如上面的0和1),我想执行一些条件检查以确定应该为给定的引脚常数写入哪个寄存器.

但是,引脚配置在编译时都是常量,所以我想从编译代码中消除条件检查.我知道无论如何优化都可能摆脱不必要的条件,但我想知道是否有办法明确地实现这种行为,因为我可能需要在将来禁用优化.

谢谢,

FROB

kin*_*nak 6

使用C++,您可以使用模板函数,如下所示:

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>();
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*nze 4

对于 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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

register0=0x00000003 register1=0x80000001
Run Code Online (Sandbox Code Playgroud)