一种在函数调用中定义新变量的方法
A way around defining new variables in function calls
我有一个在我的代码中经常调用的函数 dangerous(GEN x)
,其中 GEN
是一个 typedef
。出于调试目的,我想将 checkSafe
添加到此函数的所有实例中,例如
#ifdef DEBUG
#define dangerous(x) GEN __x = (x); if(checkSafe(__x)) dangerous(__x)
#endif
但我担心这可能无法按预期工作。做这样的事情的正确方法是什么?该函数使用过于频繁,无法单独检测每次使用,并且不希望在调试模式之外进行检查(出于各种原因)。
注意事项/注意事项:
- 同时使用同名的宏和函数。虽然它可以生成有效的 C,但您必须 1) 采取额外的预防措施以避免不必要的扩展(总是在宏之前定义函数,或者将函数名称括在 parentheses 在定义时)和 2) 仔细检查该函数的每次使用是否还包括您的检测代码。
解决方法:将原来的函数重命名为_dangerous
.
- 在各种情况下使用宏:
- 在
if
中只有一条语句:if (foo) dangerous(x);
- 来自 parent
if
的 else
:if (foo) dangerous(x); else bar();
- 将变量泄漏到 parent 命名空间时可能会造成破坏:
GEN __x = 5; dangerous(__x);
.
解决方案: 将宏包含在类似 do { ... } while(0)
.
的结构中
- 您必须考虑复制时的任何副作用,例如资源分配或 CPU 密集操作(因为
GEN
是 typedef,这可能不是问题)。
最后,您可能还想在 checkSafe 失败时进行投诉,例如通过记录错误消息,甚至中止程序。
将以上内容放在一起,您将像这样检测函数:
#ifdef DEBUG
#define dangerous(x) do { \
GEN __x = (x); \
if (checkSafe(__x)) \
_dangerous(__x); \
else \
complainAbout(__x); \
} while(0)
#else
#define dangerous _dangerous
#endif
- 如果
dangerous()
return 是您要使用的值(例如 int
)。
解决方案: 定义一个函数来检测您的原始函数并向上传递 return 值:
#ifdef DEBUG
static inline int dangerous(GEN x) {
if (checkSafe(x))
return _dangerous(x);
complainAbout(x);
return ERROR_CODE;
}
#else
#define dangerous _dangerous
#endif
我有一个在我的代码中经常调用的函数 dangerous(GEN x)
,其中 GEN
是一个 typedef
。出于调试目的,我想将 checkSafe
添加到此函数的所有实例中,例如
#ifdef DEBUG
#define dangerous(x) GEN __x = (x); if(checkSafe(__x)) dangerous(__x)
#endif
但我担心这可能无法按预期工作。做这样的事情的正确方法是什么?该函数使用过于频繁,无法单独检测每次使用,并且不希望在调试模式之外进行检查(出于各种原因)。
注意事项/注意事项:
- 同时使用同名的宏和函数。虽然它可以生成有效的 C,但您必须 1) 采取额外的预防措施以避免不必要的扩展(总是在宏之前定义函数,或者将函数名称括在 parentheses 在定义时)和 2) 仔细检查该函数的每次使用是否还包括您的检测代码。
解决方法:将原来的函数重命名为_dangerous
.
- 在各种情况下使用宏:
- 在
if
中只有一条语句:if (foo) dangerous(x);
- 来自 parent
if
的else
:if (foo) dangerous(x); else bar();
- 将变量泄漏到 parent 命名空间时可能会造成破坏:
GEN __x = 5; dangerous(__x);
.
- 在
解决方案: 将宏包含在类似 do { ... } while(0)
.
- 您必须考虑复制时的任何副作用,例如资源分配或 CPU 密集操作(因为
GEN
是 typedef,这可能不是问题)。
最后,您可能还想在 checkSafe 失败时进行投诉,例如通过记录错误消息,甚至中止程序。
将以上内容放在一起,您将像这样检测函数:
#ifdef DEBUG
#define dangerous(x) do { \
GEN __x = (x); \
if (checkSafe(__x)) \
_dangerous(__x); \
else \
complainAbout(__x); \
} while(0)
#else
#define dangerous _dangerous
#endif
- 如果
dangerous()
return 是您要使用的值(例如int
)。
解决方案: 定义一个函数来检测您的原始函数并向上传递 return 值:
#ifdef DEBUG
static inline int dangerous(GEN x) {
if (checkSafe(x))
return _dangerous(x);
complainAbout(x);
return ERROR_CODE;
}
#else
#define dangerous _dangerous
#endif