3

MFC をオンにして VS2008 で以下のコードをコンパイルすると、警告が表示されます。ブーストバージョン 1.39


include "boost/flyweight.hpp"
include "boost/flyweight/key_value.hpp"
class Foo
{
  public:
    Foo(const CString& item) : mfoo(item) {}
    const CString& getkeyvalue() const {return mfoo;}
  private:
    const CString mfoo;
};
struct Conversion
{
  const CString& operator() (const Foo& item) const {return item.getkeyvalue();}
};  

using namespace boost::flyweights;
flyweight<key_value<CString, Foo, Conversion>, tag<Foo> > flyweight_test;

上記のコードの最後の行で警告が生成されます

d:\work\sourcecode\boost1390\boost\functional\hash\extensions.hpp(72): 警告 C4800::'const wchar_t *'値を bool 'true' または 'false' に強制しています (パフォーマンス警告)
d:\work\sourcecode\boost1390\ boost\functional\hash\extensions.hpp(71) : [ ] d:\work\sourcecode\boost1390\boost\multi_index\hashedindex.hpp(1159) を使用してクラス テンプレート メンバー関数size_t boost::hash<T>::operator ()(const T &) constをコンパイル中 : クラス テンプレートのインスタンス化への参照を参照 'boost ::hash<T>' が [ ] でコンパイルされている

T=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t>>



T=ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t>>

この警告は、ハッシュされたファクトリ、MPL などを介して延々と続きます。

警告が表示される理由と、警告が生成されないようにコードを修正するにはどうすればよいですか?

編集:
修正するには、 hash_value の実装の下に追加します


template<typename CharType, typename TraitsType>
std::size_t hash_value(const ATL::CStringT<CharType, TraitsType>& s)
{
    return CStringElementTraits<typename TraitsType>::Hash(s);
}
4

5 に答える 5

3

C4800 警告は、int 式を bool に変換する必要がある場合に、コンパイラによって出力されます。

例:

int k = 11;
bool f()
{ return k; }

int 式 k は、次の内部定義から変換されます。

k == 0 => *false*
k != 0 => *true*

ブール値の定義

b == false (internally == 0) => *false*
b == true  (internally == 1) => *true*

C++ では任意の値 (0 以外) がtrueを表す可能性があるため、コンパイラは k を bool に変換する必要があります。

警告が正しく述べているように、この変換によりパフォーマンスが低下する可能性があります。

注意: コンパイラは通常、コードから正しい意味を抽出し、これを最適化するため、この警告は少し余計かもしれません。

コンパイラがサンプル コードから作成する疑似 C コード:

char f()
{
    if( k )
       return (char) 1;
    return (char) 0;
}
于 2009-10-08T16:58:18.373 に答える
3

/Wall を指定してコンパイルすると、Boost はあらゆる種類の警告を生成します。さらに、すべての警告をエラーとして処理するようにコンパイラーに指示するため、警告がまったくないことが必要になります。

Boost ヘッダーのコンパイル中に警告が表示されないようにするために、#pragma warning を使用して一時的に警告レベルをできるだけ低くし、Boost ヘッダーの処理中に残りの警告をオフにします。

// 最小の警告レベルを設定
#pragma warning(push,0)
// このレベルでもいくつかの警告が発生します
// 必要に応じて、前のプラグマでカバーされていない特定の警告を無効にします
#pragma warning(無効:4800)

#含む

// 警告レベルを復元
#pragma warning(ポップ)

これにより、コードが可能な限り最高レベルのエラー チェックでコンパイルされ、制御できないコードが正常にコンパイルされるようになります。

私が見ることができる他の唯一のオプションは、警告を無視するか、それらの警告が修正されるまでブーストコードのパッチを適用したバージョンを維持することですが、どちらもあまり魅力的ではありません.

于 2009-10-08T11:21:44.823 に答える
2

flyweight のクラスの 1 つは、おそらく hash_value 関数 (またはラッパー クラスのハッシュ) を使用して、ATL::CString からハッシュ値を計算します。これはブーストで直接定義されていないため、実装を提供する必要があります。

std::size_t hash_value(const ATL::CString& s)
{
     // ...
}

コンパイラの出力を見るだけで、CString自体がテンプレート化されているように見えるので、実装します

template<typename CharType, typename TraitsType>
std::size_t hash_value(const ATL::CString<CharType, TraitsType>& s)
{
     // calculate hash e.g. by calling hash_value(const std::string&)
}
于 2009-10-08T14:05:35.897 に答える
0

警告のソースはコードにありません。問題のあるBoostコードを修正する必要があります。

于 2009-10-08T11:30:26.553 に答える
0

その警告を修正する方法はわかりませんが、以下のコードを cpp ファイルに追加することで無効にすることができます。

#pragma warning(disable:4800)

詳細については、MSDNを参照してください。

于 2009-10-08T11:23:29.593 に答える