c - 一种在函数调用中定义新变量的方法

标签 c debugging c-preprocessor c89

我有一个函数 dangerous(GEN x),它在我的代码中经常被调用,其中 GEN 是一个 typedef。出于调试目的,我想将 checkSafe 添加到此函数的所有实例中,例如

#ifdef DEBUG
  #define dangerous(x) GEN __x = (x); if(checkSafe(__x)) dangerous(__x)
#endif

但我担心这可能无法按预期工作。做这样的事情的正确方法是什么?该函数的使用过于频繁,无法单独检测每次使用,并且不希望在外部 Debug模式下进行检查(出于各种原因)。

最佳答案

注意事项/注意事项:

  1. 同时使用同名的宏和函数。虽然它可以生成有效的 C,但您必须1) 采取额外的预防措施以避免不必要的扩展(总是在宏之前定义函数,或者在定义时将函数名称括在括号中)和2) 仔细检查函数的每次使用是否还包括您的检测代码。

解决方案:将原始函数重命名为_dangerous

  1. 在各种情况下使用宏:
    • if 中只有一条语句:if (foo) dangerous(x);
    • 来自父ifelse:if (foo) dangerous(x); else bar();
    • 当将变量泄漏到父 namespace 中时会造成破坏:GEN __x = 5;危险(__x);

解决方案:将宏包含在类似do { ... } while(0) 的结构中。

  1. 您必须考虑复制时的任何副作用,例如资源分配或 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
  1. 如果 dangerous() 返回一个您要使用的值(例如 int)。

解决方案:定义一个函数来检测您的原始函数并向上传递返回值:

#ifdef DEBUG
  static inline int dangerous(GEN x) {
    if (checkSafe(x))
      return _dangerous(x);
    complainAbout(x);
    return ERROR_CODE;
  }
#else
  #define dangerous _dangerous
#endif

关于c - 一种在函数调用中定义新变量的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42340543/

相关文章:

c - Int 到 Binary 转换说明

根本无法使用 Windows Driver Kit 构建环境声明变量

c# - 无法找到或打开 PDB 文件,正在调试 native 代码

c - 在 C 中初始化一个结构

c++ - 具有不同继承的同一类的版本

iOS 编写宏检测 3.5 英寸或 4 英寸显示器

我的 CPU 可以在每个 CPU 周期执行多个 NOP 吗?

c - typedef 何时成为实际类型?

debugging - Android NDK调试: device can't be opened

apache - Docker - 如何为 AEM 打开调试端口