2014-09-05 57 views
0

我有一大堆的#define语句,所有看起来像这样的#define d,0,它们含有从公元了一封信,从0-8的数字,用逗号分隔的宏。超载有两个参数

现在我正在尝试创建一个宏,如下所示:Overloading Macro on Number of Arguments,但这可以适用于我的情况。这个网站上的宏只适用于带有一个参数的#define,而我的有两个。

这是我目前有:

#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME 
#define TEST_MACRO(...)  GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__) 

#define _TEST_MACRO_8(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6, letter7, number7, letter8, number8)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8)) 
#define _TEST_MACRO_7(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6, letter7, number7)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7)) 
#define _TEST_MACRO_6(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6)) 
#define _TEST_MACRO_5(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5)) 
#define _TEST_MACRO_4(letter1, number1, letter2, number2, letter3, number3, letter4, number4)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4)) 
#define _TEST_MACRO_3(letter1, number1, letter2, number2, letter3, number3)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3)) 
#define _TEST_MACRO_2(letter1, number1, letter2, number2)   (PORT##letter1 |= ((1 << number1) | (1 << number2)) 
#define _TEST_MACRO_1(letter1, number1)   (PORT##letter1 |= (1 << number1)) 

如果我做的:

#define ONE D, 0 
#define TWO D, 1 
#define THREE D, 2 

TEST_MACRO(ONE); //Error: macro _TEST_MACRO_2 requires 4 arguments but only 2 given 
TEST_MACRO(ONE,TWO); //Error: macro _TEST_MACRO_4 requires 8 arguments but only 4 given 
TEST_MACRO(ONE,TWO,THREE); //Error: macro _TEST_MACRO_6 requires 12 arguments but only 6 given 

这里有什么问题吗?我该如何解决它?

此致敬礼!

编辑:

澄清一下,这里是哪里,这是会得到中使用的背景我编程8位AVR微控制器。并且知道我有这样定义的针脚:#define PIN1 A,0,其中A代表PINs字母,并且代表PIN号码。

如果我有一大堆这样定义,当我想改变它们的一些设置时,我必须一个接一个地手动完成它,就像这样:PIN_HIGH(PIN1);PIN_HIGH(PIN2);PIN_HIGH(PIN3)并且有更多的代码,乱。

所以我正在寻找一种方法来处理一个宏:PIN_HIGH(PIN1,PIN2,PIN3);。当我将它们传递给一个宏时,PIN1,PIN2,PIN3字母匹配也很重要,因为有时我可以将该pin转移到其他字母。

有关如何完成此任务的任何建议都非常值得欢迎!

+0

我想不出一个更好的方式来做到这一点......任何改进都超过欢迎! – user1806687 2014-09-05 21:30:11

+0

它更容易阅读:PIN_HIGH(PIN_1,PIN_2,PIN_8);比PORTA | =((1 << PA1)|(1 << PA2)|(1 << PA8)),并且跟踪所有PORTS和DDRS,而PINS只是做了很多工作而已,至少在我的看法。不过谢谢你的帮助。 – user1806687 2014-09-05 21:36:06

+0

我确定你可以做得比第二个例子更干净,而且几乎所有的东西都比猜测要看到哪个宏实际上正在扩展更好。但正如我所说,我不会成为与之合作的人,很明显这是你的决定。然而,你*确实问过。 :-) – 2014-09-05 21:39:31

回答

1

字符。所以,我建议遵循下面的方式。

#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME 
#define TEST_MACRO(letter,...) (PORT##letter |= GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__)) 

#define _TEST_MACRO_8(number1, number2, number3, number4, number5, number6, number7, number8) \ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8) 
#define _TEST_MACRO_7(number1, number2, number3, number4, number5, number6, number7)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) 
#define _TEST_MACRO_6(number1, number2, number3, number4, number5, number6)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) 
#define _TEST_MACRO_5(number1, number2, number3, number4, number5)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) 
#define _TEST_MACRO_4(number1, number2, number3, number4)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) 
#define _TEST_MACRO_3(number1, number2, number3)\ 
    (1 << number1) | (1 << number2) | (1 << number3) 
#define _TEST_MACRO_2(number1, number2)\ 
    (1 << number1) | (1 << number2) 
#define _TEST_MACRO_1(number1)\ 
    (1 << number1) 


TEST_MACRO(D, 1); 
TEST_MACRO(D, 0, 1); 
TEST_MACRO(D, 0, 1, 2); 

#define ONE (D, 0) 
#define TWO (D, 1) 
#define THREE (D, 2) 
#define CAR(a,b) a 
#define CDR(a,b) b 
#define F(x) CAR x 
#define R(x) CDR x 
#define TEST_MACRO_WRAP(...) TEST_MACRO(__VA_ARGS__) 
TEST_MACRO_WRAP(F(ONE), R(ONE)); 
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO)); 
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO), R(THREE)); 
+0

我真的很喜欢这个,但是有没有办法通过全** ** **,**两**,**三** **定义,而不必通过其中的一部分,如来自** ONE的字母和数字**,然后只有**两个**的数字。然后,是否有可能检查一个宏是否所有传递的字母都是相同的,如果它们不是,则抛出#error?谢谢! – user1806687 2014-09-06 10:55:44

+0

这个检查是否所有字母都是相同的,因此我必须在编译时进行,因为我的资源非常有限。再次感谢你! – user1806687 2014-09-06 10:59:13

+0

@ user1806687无法在预处理器中进行非数字相等的比较。 – BLUEPIXY 2014-09-06 11:04:05

0

ONETWOTHREE都扩大TEST_MACRO之前立即展开,所以当你说TEST_MACRO(ONE),该__VA_ARGS__宏ARG设置为D, 0(的ONE扩展),这意味着你叫_TEST_MACRO_2,因为这是两个论据。

因为你总是希望偶数的参数,你可以定义TEST_MACRO为:表示该端口没有比第一使用其他

#define TEST_MACRO(...)  GET_MACRO(__VA_ARGS__, _TEST_MACRO_4, ERROR, _TEST_MACRO_3, ERROR, _TEST_MACRO_2, ERROR, _TEST_MACRO_1, ERROR) (__VA_ARGS__) 
#define ERROR(...) #error "Odd number of arguments to TEST_MACRO" 
+0

我会试试看tommorow并让你知道。因为这里晚了,我住在哪里。 – user1806687 2014-09-05 21:32:34

+0

'#错误'错误。 – BLUEPIXY 2014-09-06 11:07:43