I am using googlemock to mock out an std::fstream
object in my unit tests, like this:
TEST_F(SomeTest, SomethingIsDoneCorrectly)
{
class MockFstream : public std::fstream {};
MockFstream lMockFstream;
// Expectations and assertions here
}
When I compile 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' via dominance
Warning 2 warning C4250: 'SomeTest_SomethingIsDoneCorrectly_Test::TestBody::MockFstream' : inherits 'std::basic_ostream<_Elem,_Traits>::std::basic_ostream<_Elem,_Traits>::_Add_vtordisp2' via dominance
I'd prefer clean build output, so I want to suppress these specific warnings, but I'm writing cross-platform code, so I'd also prefer to avoid compiler-specific #pragma
s.
Is there something I can do in the googlemock object that will hide these warnings?
It turns out that these warnings are a side-effect from some quirks in the Microsoft C++ STL. I've quoted an explanation from the relevant Microsoft Connect issue below.
My solution was simply to implement empty versions of the inherited functions in my mock:
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
}
An explanation from Microsoft about why the warning occurs:
The story here is somewhat complicated. VC has an obscure compiler option, /vd2 (documented at http://msdn.microsoft.com/en-us/library/7sf3txa8.aspx), that fixes an obscure bug involving virtual base classes. By default, VC does something that's slightly nonconformant to the C++ Standard. /vd2 changes VC's behavior to be conformant, but this inherently affects class layout. (This layout difference is why the default hasn't been changed to be conformant - that would break users attempting to mix code compiled with different major versions of VC. Our C++ Standard Library implementation forbids such mixing, but the compiler itself is somewhat more permissive.) So if users want /vd2, they have to compile everything that way.
The twist is that the layout bug (which /vd2 fixes) affects iostreams, which uses virtual base classes, and our iostreams implementation has a separately compiled component (in msvcp100.dll/libcpmt.lib/etc.). When MS builds the STL's DLL/LIB, they're compiled the default way, without /vd2. As a result, people using /vd2 couldn't use iostreams, or they'd get bizarre crashes. Yuck.
So, we added the do-nothing virtual functions _Add_vtordisp1() and _Add_vtordisp2(). Their presence makes VC perform layout completely conformantly, regardless of /vd2 being used or not, and therefore makes iostreams usable both ways.
_Add_vtordisp1() and _Add_vtordisp2() trigger warning C4250, talking about dominance. This warning is actually completely useless - it's saying that the compiler will do exactly what the Standard requires it to do. Therefore, we suppress it in the STL's headers (which must be /W4 /analyze clean). If you're deriving from fstream, you'll need to suppress this warning in your own code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With