Avoiding the dominant inheritance warning for the mocking class std :: fstream

I use googlemock to mock the std::fstream object in my unit tests, for example:

 TEST_F(SomeTest, SomethingIsDoneCorrectly) { class MockFstream : public std::fstream {}; MockFstream lMockFstream; // Expectations and assertions here } 

When compiling, I get the following warnings:

Warning 1 warning C4250: 'SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream': inherits 'std :: basic_istream <_Elem, _Traits> :: std :: basic_istream <_Elem, _Traits> :: _ Add_vtordisp1' through dominance

Warning 2 Warning C4250: "SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream": inherits "std :: basic_ostream <_Elem, _Traits> :: std :: basic_ostream <_Elem, _Traits> :: _ Add_vtordisp2 'through dominance

I would prefer clean assembly output, so I want to suppress these specific warnings, but I write cross-platform code, so I would also prefer to avoid the #pragma s compiler-specific ones.

Is there something I can do in the googlemock object that will hide these warnings?

+7
source share
1 answer

It turns out that these warnings are a side effect of some quirks in the Microsoft C ++ STL. I provided an explanation from the corresponding Microsoft Connect problem below.

My solution was to simply implement empty versions of the inherited functions in my layout:

 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 explanation of why the warning occurs:

The story here is somewhat complicated. VC has an obscure compiler option, / vd 2 (documented at http://msdn.microsoft.com/en-us/library/7sf3txa8.aspx ), which fixes an obscure error involving virtual base classes. By default, VC does something a little inconsistent with the C ++ standard. / Vd2 changes the behavior of VC to be compatible, but this essentially affects the layout of the class. (This difference in layouts is the reason that the default value has not been changed to be compatible - this will cause users to try to compile code compiled with various major versions of VC. Our implementation of the standard C ++ library prohibits such mixing, but the compiler itself is somewhat more permissive.) Therefore, if users want / vd 2, they must compile it all.

The twist is that the layout error (which fixes / vd 2) affects iostreams, which uses virtual base classes, and our implementation of iostreams has a separately compiled component (in msvcp100.dll / libcpmt.lib / etc.). When MS builds the STL DLL / LIB, they compile by default, without / vd 2. As a result, people using / vd 2 cannot use iostreams, or they will get bizarre crashes. Ugh.

So, we added the do-nothing _Add_vtordisp1 () and _Add_vtordisp2 () virtual functions. Their presence makes VC a complete layout regardless of which / vd 2 is used, and therefore makes iostreams usable in both directions.

_Add_vtordisp1 () and _Add_vtordisp2 () trigger the C4250 warning, indicating dominance. This warning is actually completely useless - he says that the compiler will do exactly what the Standard requires. Therefore, we suppress it in the STL headers (which should be / W4 / parsed clean). If you exit fstream, you need to suppress this warning in your own code.

+7
source

All Articles