c++ - 匹配开始/结束分析调用

标签 c++ macros profiling do-while

我目前正在将分析系统实现到应用程序中。

我有两个基于编译器标志 (NDEBUG) 定义的宏函数。当未定义 NDEBUG 时,这两个函数 (profilingStart/profilingEnd) 生成分析报告,显示调用 profilingStart 的时间与调用 profilingEnd 的时间。

问题是可能会发生不匹配——即调用 profilingStart 而未调用 profilingEnd 的情况(反之亦然)。我的代码已经在运行时识别出这些情况,但如果由于这种不匹配而在编译时导致错误,那将是更可取的。

一个建议是使用 do{...}while();构造以确保分析功能正确配对。开始宏函数将包含 do{,结束宏将包含 }while()。如果缺少一个,我们会在编译时出错。但是,这有一些问题——您只能在正在分析的函数的开头和结尾使用 profilingStart() 和 profilingEnd() 调用,因为在函数内使用它们可能会影响局部变量的范围(因为它们可能会由于 do{...}while() 调用而超出范围)。

我的另一个想法是在 profilingStart 函数中声明一个变量,然后尝试在 profilingEnd 函数中修改该变量的内容。这可以防止范围问题,如果变量从未声明过,则会产生编译器错误。但是,我永远不会有任何方法来验证变量的内容是否在 end 函数中被修改。这只能帮助解决一半的问题,因为它不会验证 profilingEnd 函数的调用。

一如既往地欢迎任何意见。提前致谢。

编辑:我对范围的评论可能有些困惑。 profilingStart() 和 profilingEnd() 将始终在同一个函数中调用。它们可能不会在函数的最开始/最结束时被调用。这是我的意思的一个例子:

int DoSomething(void)
{
   profilingStart();
   int a;
   DoMath(a);
   profilingStop();
   return a; // a is out of scope here, as the do{...}while(0) construct has gone out of scope
}

最佳答案

在 C++ 中,一种解决方案是使用“RAII”习惯用法。像这样:

class Profiler {
  public:
    Profiler() { profilingStart(); }
    ~Profiler() { profilingEnd(); }
}

然后你像这样使用它:

{ // start of block you want to profile
    Profiler prof;
    ...
}

这将确保 profilingEnd 即使在出现异常、提前返回、break 等情况下也会被调用。也就是说,它绝对保证调用是成对的。

不过,它确实需要将您想要分析的代码放在一个 block 中。

[编辑]

我没有注意到您希望能够将 profilingEnd 放在与 profilingStart 不同的 block 中。

有关如何处理此问题的想法,请参阅下面@Roddy 的评论;例如通过让析构函数检查以确保分析器在对象被析构时已经停止。虽然这不会在编译时发现问题,但会在运行时“接近”问题。

关于c++ - 匹配开始/结束分析调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6601874/

相关文章:

php - MySQL 查询和 PHP 脚本调整 : How can I find the problems?

profiling - 是否有相当于 Python 的 cProfile 的 Julia 分析器?

c++ - 当与服务器的连接未保留时使用 SSL

c++ - 为什么 xcode IDE 认为 `friend` 是保留字

concurrency - 防止 Fn 在它已经运行时被再次调用

c++ - 编写宏

windows - 使用 xperf 获取符号

c++ - 读取二进制文件,Linux Buffer Cache

c++ - VS 2017 中的模块支持状态

php - 如何有条件地禁用代码