【发布时间】:2011-07-06 19:30:47
【问题描述】:
我目前正在将分析系统实施到应用程序中。
我有两个基于编译器标志 (NDEBUG) 定义的宏函数。当未定义 NDEBUG 时,这两个函数(profilingStart / profilingEnd)会生成分析报告,显示调用 profilingStart 的时间与调用 profilingEnd 的时间。
担心可能发生不匹配 - 即,当 profilingStart 已被调用但 profilingEnd 未调用时(反之亦然)。我的代码会在运行时识别出这些情况,但如果在编译时由于这种不匹配而导致错误会更好。
一个建议是使用 do{...}while();构造以确保分析功能正确配对。开始宏函数将包含 do{,而结束宏将包含 }while()。如果缺少一个,我们会在编译时得到一个错误。但是,这有一些问题 - 您只能在正在分析的函数的开始和结束处使用 profilingStart() 和 profilingEnd() 调用,因为在函数中使用它们可能会影响局部变量的范围(因为它们可能会由于 do{...}while() 调用而超出范围。
我的另一个想法是在 profilingStart 函数中声明一个变量,然后尝试在 profilingEnd 函数中修改该变量的内容。这可以防止范围问题,如果从未声明变量,则会生成编译器错误。但是,我永远不会有任何方法来验证变量的内容是否在 end 函数中被修改。这只有助于解决一半的问题,因为它不会验证 profilingEnd 函数的调用。
一如既往地感谢任何 cmets。提前致谢。
编辑:我对范围的评论可能有些混乱。 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
}
【问题讨论】:
-
匹配开始和结束调用:这分别是构造函数和析构函数的工作。大概您已经考虑过这一点,并将其视为解决问题的方法。为什么?
-
@Alf:这并不能真正解决 OP 的问题。您仍然必须在正确的位置调用
delete,或者人为地引入额外的嵌套范围以在正确的时间自动调用析构函数。 -
@jmein 那是我的目标。
-
另外,您的第二种方法仍然存在范围问题,即 start 和 end 函数必须在同一个范围块内发出(否则 end 函数可能看不到 start 变量)。换句话说,您不能在一种方法中调用 start 并在另一种方法中结束。您是否有不想使用 gprof 的原因?
-
@Pace:Gprof (AFAIK) 具有函数级粒度。
标签: c++ macros profiling do-while