出于调试目的,我定义了以下宏
#define SECTION_TIME(out, s) GPIO_SetOut(out); \
s \
GPIO_ClrOut(out);
用法:
SECTION_TIME(GPIO_fooOut,
foo();
bar();
foo=bar^foo;....;....;
)
目标:需要确定一些代码的时间。 有时这个宏不编译。我错过了解某事吗? PS:我也尝试用{}
包围我的代码error: macro "SECTION_TIME" passed 6 arguments, but takes just 2
答案 0 :(得分:2)
当代码像鸭子一样走路并像鸭子一样说话时,它的表现就像鸭子一样。我的意思是SECTION_TIME(GPIO_fooOut, ...)
(有点)看起来像一个陈述,而实际上它映射到3个或更多的陈述。这很糟糕,你应该努力使它成为一个陈述。
这实际上并不困难,用于此的常用习惯是将宏内容包装在do { ... } while (0)
中,而不用一个尾随分号(以便将尾随分号提供给结尾)宏调用。)
所以你至少应该将你的宏改为
#define SECTION_TIME(out, s) \
do { \
GPIO_SetOut(out); \
s; \
GPIO_ClrOut(out); \
} while (0)
另请注意,您应该在宏中放置s
的终止分号而不是参数。因此应该像
SECTION_TIME(GPIO_fooOut,
foo();
bar();
foo=bar^foo;....;....
);
根据使用情况,使用SETION_TIME_BEGIN和SECTION_TIME_END的建议可能是更好的解决方案。
答案 1 :(得分:0)
使用可变参数宏解决
#define BOARD_SECTION_TIME(out, ...) do { \
GPIO_SetOut(out); \
__VA_ARGS__ \
GPIO_ClrOut(out); \
} while(0)
答案 2 :(得分:0)
我也使用__VA_ARGS__
的方式,但我也通过定义第二个宏来制作一些类似咖喱的语法,该名称位于第一个宏中:
#define SECTION_TIME(out) \
do { \
/* remember to save the value, so that the same output is always cleared and can be used in the second one */ \
decltype(out) _o = out; \
GPIO_SetOut(_o); \
SECTION_TIME_BLOCK1
#define SECTION_TIME_BLOCK1(...) \
{__VA_ARGS__}; \
GPIO_ClrOut(_o); \
} while(0);
它可以像这样使用:
SECTION_TIME(GPIO_fooOut) (
foo();
bar();
foo=bar^foo;
//....;....;
);
您会看到out
输入参数是一个单独的元组,并且语法类似于if
的语法,例如,只有括号不同。如果你只想定义一个宏,你可以说代码参数应该是一个元组:
// this macro is only a help to remove the brackets and can be used in multiple definitions
#define PP_REMOVE_BRACKETS(...) __VA_ARGS__
/**
* \param code a tuple containing the code you want to run
**/
#define SECTION_TIME(out, code) \
do { \
/* remember to save the value, so that the same output is always cleared */ \
decltype(out) _o = out; \
GPIO_SetOut(_o); \
{PP_REMOVE_BRACKETS code}; \
GPIO_ClrOut(_o); \
} while(0);
可以这样使用:
SECTION_TIME(GPIO_fooOut, (
foo();
bar();
foo=bar^foo;
//....;....;
));