Я хочу сказать компилятору VC ++ для компиляции всего кода. Это можно сделать? - PullRequest
1 голос
/ 19 сентября 2008

Я использую VS2005 VC ++ для неуправляемого C ++. У меня есть VSTS, и я пытаюсь использовать инструмент покрытия кода, чтобы выполнить две вещи в отношении модульных тестов:

  1. Посмотрите, какая часть моего тестируемого кода выполняется
  2. Посмотрите, сколько методов моего тестируемого кода (если таковые имеются) вообще не тестируются модулем

Настройка инструмента покрытия кода VSTS (см. текст ссылки ) и выполнение задачи № 1 были простыми. Однако № 2 стал для меня неожиданным испытанием. Вот мой тестовый код.

class CodeCoverageTarget
{
public:
    std::string ThisMethodRuns() {
         return "Running";
    }

    std::string ThisMethodDoesNotRun() {
        return "Not Running";
    }
};



#include <iostream>
#include "CodeCoverageTarget.h"
using namespace std;
int main()

{
    CodeCoverageTarget cct; 
    cout<<cct.ThisMethodRuns()<<endl;
}

Когда оба метода определены в классе, как указано выше, компилятор автоматически удаляет ThisMethodDoesNotRun () из файла obj. Если я перенесу его определение за пределы класса, то оно будет включено в файл obj, и инструмент покрытия кода покажет, что он вообще не использовался. В большинстве случаев я хочу, чтобы компилятор сделал это исключение для меня, но для инструмента покрытия кода он побеждает значительную часть значения (например, поиск непроверенных методов). Я попробовал несколько вещей, чтобы сказать компилятору перестать быть умным для меня и компилировать все, но я в тупике. Было бы неплохо, если бы средство покрытия кода компенсировало это (я полагаю, сканируя исходный код и сопоставляя его с выходными данными компоновщика), но я не нашел ничего, что могло бы предложить, чтобы он включал специальный режим. Я полностью упускаю что-то простое здесь или это невозможно с помощью компилятора VC ++ + инструмента покрытия кода VSTS?

Заранее спасибо, КГБ

Ответы [ 5 ]

1 голос
/ 20 сентября 2008

Один из способов гарантировать, что ваши функции не удаляются - это экспортировать их. Вы можете сделать это, добавив __declspec(dllexport) в ваши объявления функций. Лучше всего обернуть это в макрос препроцессора C, чтобы вы могли отключить его, так как он зависит от компилятора, и вы не захотите, чтобы все ваши сборки экспортировали символы. Другой способ экспортировать функции - создать файл .DEF .

Если проблема заключается во встраивании, вы также можете успешно выполнить команду __declspec(noinline).

Является ли ваш код в статической библиотеке, которая затем компилируется в тестовый EXE / DLL? Компоновщик автоматически удалит объектные файлы без ссылок, которые находятся в статических библиотеках. Пример: если статическая библиотека содержит a.obj и b.obj и EXE / DLL, которую вы связываете с ссылочными символами из b.obj, но не a.obj, то содержимое a.obj не будет связано с исполняемый файл или DLL. Однако после повторного прочтения вашего описания это не похоже на то, что здесь происходит.

1 голос
/ 20 сентября 2008

Вы можете попытаться добавить строку кода для вызова функции, только если какое-либо условие истинно, и гарантировать, что это условие никогда не будет истинным. Просто убедитесь, что компилятор не может понять это. Например,


int main(int argc, char **argv)
{
  if(argv == NULL)  // C runtime says this won't happen
    someMethodWhichIsntReallyEverCalled();
}
0 голосов
/ 20 сентября 2008

Другим вариантом является переключение между встроенными и не встроенными функциями на основе вашей сборки с использованием файлов .inl, например:

в файле foo.inl:

inline std::string Foo::ThisMethodDoesNotRun()
{
    return "Not Running";
}

в foo.h:

#if !COVERAGE_BUILD
#include "foo.inl"
#endif

в foo.cpp:

#if COVERAGE_BUILD
#define inline
#include "foo.inl"
#endif
0 голосов
/ 20 сентября 2008

Извините, я должен был уточнить, что я строю режим отладки с встраиванием и отключением всей оптимизации. Кроме того, код удаляется еще до того, как происходит встраивание, поскольку на него никогда не ссылаются, чтобы он даже рассматривался для встраивания.

0 голосов
/ 19 сентября 2008

Отключить встраивание функций. Самый простой способ сделать это - просто скомпилировать в режиме отладки.

Редактировать: увидев ваше разъяснение, я обнаружил, что мой ответ ошибочен. Возможно, если вы переместили тело функции в другой раздел файла .h, используя ключевое слово «inline»?

...