8

ユニットテストでオブジェクトをモックアウトするために、次のように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> :: std :: basic_istream <_Elem、_Traits> :: _ Add_vtordisp1'

警告2警告C4250:'SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream':継承'std :: basic_ostream <_Elem、_Traits> :: std :: basic_ostream <_Elem、_Traits> :: _ Add_vtordisp2'

クリーンなビルド出力を好むので、これらの特定の警告を抑制したいのですが、クロスプラットフォームのコードを書いているので、コンパイラー固有#pragmaのコードも避けたいと思います。

これらの警告を非表示にするgooglemockオブジェクトでできることはありますか?

4

1 に答える 1

8

これらの警告は、Microsoft C++STLのいくつかの癖による副作用であることが判明しました。以下に、関連するMicrosoftConnectの問題からの説明を引用しました。

私の解決策は、継承された関数の空のバージョンをモックに実装することでした。

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 / etc)があることです。MSがSTLのDLL/LIBをビルドするとき、それらは/vd2なしでデフォルトの方法でコンパイルされます。その結果、/ vd2を使用しているユーザーはiostreamを使用できませんでした。そうしないと、奇妙なクラッシュが発生します。うん。

そこで、何もしない仮想関数_Add_vtordisp1()と_Add_vtordisp2()を追加しました。それらの存在により、/ vd2が使用されているかどうかに関係なく、VCは完全に準拠してレイアウトを実行するため、iostreamを両方の方法で使用できるようになります。

_Add_vtordisp1()および_Add_vtordisp2()は、支配について話している警告C4250をトリガーします。この警告は実際には完全に役に立たない-それはコンパイラが標準がそれをすることを要求することを正確に行うであろうと言っている。したがって、STLのヘッダー(/ W4 / analogze cleanである必要があります)でそれを抑制します。fstreamから派生している場合は、独自のコードでこの警告を抑制する必要があります。

于 2013-01-23T18:56:10.637 に答える