c++ - 避免模​​拟 std::fstream 类的 "inheritance by dominance"警告

标签 c++ visual-c++ mocking compiler-warnings fstream

我正在使用 googlemock在我的单元测试中模拟一个 std::fstream 对象,像这样:

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

当我编译时,我收到以下警告:

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

我更喜欢干净的构建输出,所以我想抑制这些特定的警告,但我正在编写跨平台代码,所以我也更喜欢避免特定于编译器的 #pragma

我可以在 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
}

explanation from Microsoft关于为什么会出现警告:

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.

关于c++ - 避免模​​拟 std::fstream 类的 "inheritance by dominance"警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14487241/

相关文章:

Python,模拟 : raise exception

c++ - 使用mci发送字符串C++播放MP3

c++ - C++中可重用的成员函数

java - java/静态模拟中静态调用中创建的对象

c++ - std::move on const char* 完美转发

c++ - C++:如何正确使用#include <协程>中可用的generator <>,task <>和lazy <>类?

c++ - 为什么将函数包装到 lambda 中可能会使程序更快?

c++ - 如何将字符串传递给 ofstream::open 作为文件名

c - 如何在 MSVC 中访问 libsndfile-1.dll 中的函数?

java - 如何在 Clojure 中模拟 Java 对象