я использую googlemock издеваться std::fstream
объект в моих модульных тестах, вот так:
TEST_F(SomeTest, SomethingIsDoneCorrectly)
{
class MockFstream : public std::fstream {};
MockFstream lMockFstream;
// Expectations and assertions here
}
Когда я компилирую, я получаю следующие предупреждения:
Предупреждение 1 предупреждение C4250: ‘SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream’: наследует ‘std :: basic_istream<_Elem, _Traits> :: станд :: basic_istream<_Elem, _Traits> :: _ Add_vtordisp1 ‘через доминирование
Предупреждение 2, предупреждение C4250: ‘SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream’: наследует ‘std :: basic_ostream<_Elem, _Traits> :: станд :: basic_ostream<_Elem, _Traits> :: _ Add_vtordisp2 ‘через доминирование
Я бы предпочел чистый вывод сборки, поэтому я хочу подавить эти конкретные предупреждения, но я пишу кросс-платформенный код, поэтому я бы также предпочел избегать специфичных для компилятора #pragma
s.
Есть ли что-то, что я могу сделать в объекте googlemock, который будет скрывать эти предупреждения?
Оказывается, что эти предупреждения являются побочным эффектом некоторых причуд в Microsoft C ++ STL. Я процитировал объяснение соответствующей проблемы Microsoft Connect ниже.
Мое решение состояло в том, чтобы просто реализовать пустые версии унаследованных функций в моем макете:
TEST_F(SomeTest, SomethingIsDoneCorrectly)
{
class MockFstream : public std::fstream
{
void _Add_vtordisp1() { } // Required to avoid VC++ warning C4250
void _Add_vtordisp2() { } // Required to avoid VC++ warning C4250
};
MockFstream lMockFstream;
// Expectations and assertions here
}
объяснение от Microsoft о том, почему происходит предупреждение:
История здесь несколько сложная. VC имеет неясную опцию компилятора, / vd2 (задокументировано в http://msdn.microsoft.com/en-us/library/7sf3txa8.aspx), которая исправляет скрытую ошибку, связанную с виртуальными базовыми классами. По умолчанию VC делает что-то, что немного не соответствует стандарту C ++. / vd2 изменяет поведение VC, чтобы оно соответствовало требованиям, но это по сути влияет на макет класса. (Это различие в расположении является причиной того, что значение по умолчанию не было изменено, чтобы быть совместимым — это сломало бы пользователей, пытающихся смешивать код, скомпилированный с различными основными версиями VC. Наша реализация Стандартной библиотеки C ++ запрещает такое смешивание, но сам компилятор несколько более допустим .) Так что, если пользователи хотят / vd2, они должны скомпилировать все таким образом.
Суть в том, что ошибка компоновки (которую исправляет / vd2) затрагивает iostreams, которая использует виртуальные базовые классы, а наша реализация iostreams имеет отдельно скомпилированный компонент (в msvcp100.dll / libcpmt.lib / и т.д.). Когда MS создает библиотеки DLL / LIB STL, они компилируются по умолчанию, без / vd2. В результате люди, использующие / vd2, не могут использовать iostreams, иначе они получат странные сбои. Тьфу.
Итак, мы добавили виртуальные функции бездействий _Add_vtordisp1 () и _Add_vtordisp2 (). Их присутствие заставляет VC выполнять компоновку полностью согласованно, независимо от того, используется / vd2 или нет, и поэтому делает iostreams пригодными для использования в обоих направлениях.
_Add_vtordisp1 () и _Add_vtordisp2 () вызывают предупреждение C4250, говорящее о доминировании. Это предупреждение на самом деле совершенно бесполезно — оно говорит о том, что компилятор будет делать именно то, что требует стандарт. Поэтому мы подавляем его в заголовках STL (которые должны быть / W4 / анализировать чисто). Если вы наследуете от fstream, вам нужно подавить это предупреждение в своем собственном коде.
Других решений пока нет …