Проблема в том, что я не вижу ничего о путях, которые не "проверяют".
Если это означает, другими словами, что вы ищете не только набор кодовых точек, которые фактически выполняются, но также и набор кодовых точек, которые каким-то образом «помечены», как ожидается, будут выполнены, чтобы, возможно, наконец сообщить Разница, у меня может быть очень опасное решение. Это работает для меня на MSVC 2010 и 2013.
Подход состоит в том, чтобы использовать инициализацию статических переменных до запуска программы, но поскольку все точки кода находятся в функциях и, следовательно, «точка статического анкер» должна быть каким-то образом помещена туда, поэтому функция c ++ в отложенная инициализация статических переменных функций должна быть преодолена.
Это представляется возможным путем добавления косвенного обращения через класс шаблона (X) со статической переменной-членом (progloc_), чтобы обеспечить инициализацию для параметра шаблона, который, в свою очередь, является структурой-оберткой, которая транспортирует необходимую информацию (_. 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_);
Трюк S__LINE__, который используется в ProgLocation - ctor, взят из здесь, на 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;
}
};
Может быть, есть много проблем, связанных с этим подходом, которые я пока не вижу и делаю его невыполнимым для вашего случая, и, как отмечали другие, использование инструментов статического анализа кода в большинстве случаев является лучшим решением.
EDIT:
Только что обнаружил, что предоставленное решение обсуждалось ранее в другом контексте:
неотсроченный статический член-инициализация-для-шаблоны-в-НКУ