【发布时间】:2013-06-15 11:51:21
【问题描述】:
我的模式基本上是一些样板代码,中间有一部分变化
if(condition){
struct Foo m = start_stuff();
{ m.foo = bar(1,2); m.baz = 17; } //this part varies
end_stuff();
}
是否可以制作一个将中间代码块作为参数的宏? C 中宏扩展的规则似乎非常复杂,所以我不确定将来是否有任何极端情况会来咬我(特别是,如果我的代码,我不明白宏参数是如何分离的有逗号)。
#define MY_MACRO(typ, do_stuff) do { \
if(condition){ \
struct typ m = start_stuff(); \
do_stuff; \
end_stuff(); \
} \
}while(0)
//usage
MY_MACRO(Foo, {
m.foo = bar(1,2);
m.baz = 17;
});
到目前为止,我唯一想到的是如果我在宏中使用循环语句,break 和 continue 会被捕获,这对于我的特定用例来说是一个可以接受的折衷方案。
编辑:当然,如果可以的话,我会使用函数。我在这个问题中使用的示例是简化的,并没有展示只能与宏魔法一起使用的位。
【问题讨论】:
-
do-while-false 是一个标准的习惯用法,如果需要,您可以跳出宏。我对宏的唯一保留是它使调试变得困难,尤其是在崩溃情况下。如果有一个大约 100 行的长宏块,并且在运行 5 小时后,代码在对宏的数百次调用中的某处崩溃,您将很难跟踪它。
-
对于编译错误,使用clang。它识别巨大宏中的语法错误。对于运行时错误,我通常使用
gcc -E prog.c|grep -v ^#|indent > prog-dbg.c,然后编译并将prog-dbg.c链接到其他代码。它很笨拙但很有效。 -
您的概念似乎还可以……但是您为什么不做一个回调函数构造以使您的生活更轻松?内联速度很重要吗?正如@cup 指出的那样,调试起来很痛苦。
-
@AhmedMasud:我应该在我的问题中提到样板包含一些不能作为函数参数传递的东西(结构的类型,其他一些东西的名称)并且我还需要在这一切之上做一些
##黑魔法。将结构作为参数接收的回调函数可能适用于问题中的示例,但在我的真实代码中,唯一的选择是回到手动编写样板。 -
@missingno aaah ...那么你需要让你的魔法更神奇我会发布一个替代方法你能预测编译器吗?是海合会吗?