【问题标题】:Create macro in C that traces current scope在 C 中创建跟踪当前范围的宏
【发布时间】:2019-10-12 10:37:47
【问题描述】:

在 C++ 中,对象构造函数和析构函数可用于在代码执行期间跟踪范围,如下所示:

#define TRACE(msg) Helper trace_helper(msg);
class Helper {
    const char* _name;
    Helper(const car* name) {
        _name = name;
        printf(“enter %s”, name);
    }
    ~Helper() { printf(“exit %s”, _name); }
};

这让我可以跟踪我的代码,例如

main() {
TRACE(“main”)
    for(...) {
         foo();
     }
}

void foo() {
    TRACE(“foo”)
     do some stuff
     if(condition) {
         TRACE(“inner block”)
          do some stuff
     }
}

这对于分析代码很有用。

现在,在 C 中没有可用的构造函数和析构函数,我想知道是否仍然可以创建一个 TRACE 宏,它只需要一行并且还跟踪范围的退出?

【问题讨论】:

  • 在实际构建代码之前创建一个预构建步骤来做一些魔术是否可以接受?如果是这样,我只需将所有 {} 替换为一些记录块的代码。
  • @MartinB。这听起来是个好主意,您将如何创建一个定位到 { } 的预构建事件?

标签: c macros


【解决方案1】:

您所要求的在标准 C 中是不可能的;但取决于您的编译器,它可能有一个属性。在 GCC 中,cleanup 属性可能可以做你想做的事情

#include <stdio.h>
void tracemsg(void* ctx){
    printf("scope exit\n");
}
#define SCOPE_CHECK \
    void* ctx __attribute__((cleanup (tracemsg)));

int main(){
    {
        SCOPE_CHECK;//gets printed last
        printf("in scope\n");
        printf("in scope\n");
        printf("in scope\n");
        printf("in scope\n");
    }
}

【讨论】:

  • 这看起来不错。我可以以某种方式检查正在使用的编译器是否支持此属性?
  • gcc 和 clang 都支持这个。在微软的 C 编译器中有 try、catch 和 finaly 大概可以达到类似的结果。
  • 但是如何检查使用的编译器是否支持该属性,如果不支持,我可以输出有意义的编译错误?
  • 您只需编译您的代码,如果它不支持它,代码将无法编译...
  • 当然,但通常这些编译错误非常神秘。我想使用#error "custom error message" 输出一个清晰的语句
猜你喜欢
  • 1970-01-01
  • 2019-01-23
  • 2013-06-25
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
  • 1970-01-01
相关资源
最近更新 更多