问题是我不会看到任何关于没有“检查”的路径。
如果这意味着换句话说,您不仅要查找实际执行的代码点集,还要查找已按预期执行以某种方式“标记”以最终报告差异的代码点集,我可能有一个非常危险的解决方案。它适用于我的 MSVC 2010 和 2013。
方法是利用静态变量的预程序启动初始化,但由于所有代码点都在函数中,因此必须以某种方式将“静态锚点”放在那里,因此,c++延迟初始化静态的特性必须克服函数变量。
这似乎可以通过通过带有静态成员变量 (progloc_) 的模板类 (X) 添加间接来执行每个模板参数的初始化,而模板参数又是传输所需信息的包装器结构 (_.FILE ._ "在“ _.LINE ._”行。
综上所述,实现这一目标的最重要代码如下所示:
template <class T> class X {
public:
static T progloc_;
};
template <class T> T X<T>::progloc_;
#define TRACE_CODE_POINT \
struct ProgLocation { \
public: \
std::string loc_; \
ProgLocation() : loc_(std::string(__FILE__ " at line " S__LINE__)) \
{ \
TestFw::CodePoints::Test::imHere(loc_); \
} \
}; \
TestFw::CodePoints::X<ProgLocation> dummy; \
TestFw::CodePoints::Test::iGotCalled(dummy.progloc_.loc_);
ProgLocation-ctor 中使用的 S__LINE__ 技巧来自SO 上的此处。
#define S(x) #x
#define S_(x) S(x)
#define S__LINE__ S_(__LINE__)
要跟踪,使用以下内容:
class Test
{
private:
typedef std::set<std::string> TFuncs;
static TFuncs registeredFunctions;
static TFuncs calledFunctions;
public:
static int imHere(const std::string fileAndLine)
{
assert(registeredFunctions.find(fileAndLine) == registeredFunctions.end());
registeredFunctions.insert(fileAndLine);
return 0;
}
static void iGotCalled(const std::string fileAndLine)
{
if (calledFunctions.find(fileAndLine) == calledFunctions.end())
calledFunctions.insert(fileAndLine);
}
static void report()
{
for (TFuncs::const_iterator rfIt = registeredFunctions.begin(); rfIt != registeredFunctions.end(); ++rfIt)
if (calledFunctions.find(*rfIt) == calledFunctions.end())
std::cout << (*rfIt) << " didn't get called" << std::endl;
}
};
也许有很多与这种方法相关的问题,我还没有看到,这对于您的情况来说是不切实际的,正如其他人指出的那样,在大多数情况下,使用静态代码分析工具是更好的解决方案。
编辑:
刚刚发现之前在另一个上下文中讨论过提供的解决方案:
gcc 中模板的非延迟静态成员初始化