Избежание «наследования по доминированию» предупреждение для ложного класса std :: fstream

я использую 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 ‘через доминирование

Я бы предпочел чистый вывод сборки, поэтому я хочу подавить эти конкретные предупреждения, но я пишу кросс-платформенный код, поэтому я бы также предпочел избегать специфичных для компилятора #pragmas.

Есть ли что-то, что я могу сделать в объекте googlemock, который будет скрывать эти предупреждения?

8

Решение

Оказывается, что эти предупреждения являются побочным эффектом некоторых причуд в 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, вам нужно подавить это предупреждение в своем собственном коде.

8

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector