我要实现以下目标:
假设我们有一些功能foo
。我们还有两个功能pre
,post
分别检查它的前置条件和后置条件。我们有一些foo
函数调用。现在,我想foo
用一个“受保护的”呼叫代替每个呼叫,该“受保护的”呼叫检查条件是否得到满足。必须使用编译器标志进行切换。递归foo
调用也必须被替换。
我能想到的最好的事情如下:
#ifdef NDEBUG
int foo_orig(int n);
int foo(int n)
{
int r;
assert(pre(n));
r = foo_orig(n);
assert(post(n, r));
return r;
}
int foo_orig(int n)
#else
int foo(int n)
#endif
{
/* The body of the function foo... */
foo(n); /* recursive call */
}
我知道这很笨拙且丑陋。有什么更好的方法吗?最好我只想拥有一个可以自动执行所有操作的宏,即
GUARD(foo, pre, post, arguments, return_type)
那有可能吗?
编辑
已提出嵌入建议,pre
并将其post
呼入foo
正文。这可能适用于pre
,但是因为post
我们需要用相当复杂的代码替换每个return语句。如果在foo
正文中更改了参数值,这也将不起作用。
因此,这更具打字性。我想要一些简单易用的东西。
你的意思是这样的吗?
#include <stdio.h>
#if 1
#define foo(...) GUARD(foo, pre, post, (__VA_ARGS__))
#define GUARD(F, PRE, POST, ARGS) (POST(F(PRE ARGS)))
//exactly equivalent to #define foo(...) post(foo(pre(__VA_ARGS__)))
#endif
int pre(int n) { printf("pre %d\n", n); return n; }
int post(int n) { printf("post %d\n", n); return n; }
int (foo)(int n) {
printf("%d\n", n);
return n == 0 ? 0 : foo(n - 1);
}
int main(void) {
foo(6);
}
#define
d宏的一个功能是不允许它们递归扩展,因此您始终可以定义一个宏,例如#define foo(X) foo(Y(X))
-foo
扩展中的单独保留,并标记为不再替换。它专门用于这样的用途,以便可以将函数调用无缝地替换为同一调用的包装版本,而无需重命名,即可用于调试或其他此类目的。
(请注意,宏,是不知道C'S语法,将取代声明的foo
,以及有机会的话,这是没有好,通常你的身体之后,或者在不同的文件放置宏定义,但如果你需要包装要进行递归,您也可以使用鲜为人知的带括号的函数名语法来解决此问题)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句