2015-08-15 25 views
1

有没有更简单/更简单的方法来做到这一点?C宏:基于参数值的条件代码?

以下工作正常,但我认为它很丑 - 我想要一个解决方案,不需要单独的#define为每个可能的无效值传递为“端口”。

#define _port_A_config_digital(mask)  // do nothing; this port is always digital 
#define _port_B_config_digital(mask)  AD1PCFGSET = (mask) 
#define _port_C_config_digital(mask) 
#define _port_D_config_digital(mask) 
#define _port_E_config_digital(mask) 
#define _port_F_config_digital(mask) 
#define _port_G_config_digital(mask) 
#define _port_H_config_digital(mask) 
#define _port_I_config_digital(mask) 
#define _port_J_config_digital(mask) 
#define _port_K_config_digital(mask) 

#define ConfigDigitalBits(port, mask)  _port_##port##_config_digital(mask) 

如果 “端口” 是什么其他比B,我想有一个空语句。

我想摆脱所有#defines以外的东西。

我想这样做,因为在这个MCU上除了B以外的所有端口都是总是数字,没有什么可以做的。

但调用ConfigDigitalBits()应该是任何端口的有效做法。

+0

如果端口是在运行时计算的变量,然后ConfigDigitalBits(端口,掩模)不能减少到一个空语句,因为将至少需要被运行时代码,以测试是否端口==乙如果我误解你要找的东西,请澄清你的问题。 – sifferman

+0

@sifferman:猜猜我不清楚,对不起。这实际上有效,它只是丑陋的。这个想法是我想在编译时测试传递的参数“port”是否为'B'。传递的参数将永远是一个常量标记(但并不总是相同的常量标记 - 可能只是A,B,C .. K)。 –

+0

我想不出更好的办法。 – melpomene

回答

0

你可以做类似

#define CONFIG_DIGITAL_BITS(PORT, MASK) \ 
    do { if (PORT == 'B') AD1PCFGSET = (MASK); } while (0) 

和信任(或通过读取组件检查)编译器,以评估在编译时的if条件。也就是说,

CONFIG_DIGITAL_BITS('B', 0x42); 

将生成的代码只

AD1PCFGSET = 0x42; 

CONFIG_DIGITAL_BITS('A', 0x42); 

将在所有生成代码。

上面提出的代码有一个问题,它忽略了错误。例如,

CONFIG_DIGITAL_BITS('Z', 0x42); 

很高兴地编译,虽然没有端口Z。你可以在这里设置assert,但这只会在运行时捕获错误。

一旦你做到了这一点,考虑在整体上摆脱宏,并使用inline函数,而不会传播。

inline void 
config_digital_bits(const char port, const unsigned mask) 
{ 
    assert(port >= 'A' && port <= 'K'); 
    if (port == 'B') 
    AD1PCFGSET = mask; 
}