2016-08-03 8 views
1

私はC++のconstexprを試しています。私は、FNV-1aハッシュを使用してHashedStringクラスを実装しています。msvc 14のコンパイル時に私のconstexprを評価する方法

ビジュアルスタジオ2015アップデート3は、コンパイル時にconstexprを評価していないようです。

static_assertを追加しましたが、エラーは表示されません。 私のテストの逆アセンブリでは、事前計算された値の代わりにconstexpr関数への明示的な呼び出しがあることは明らかです。

私もg ++とclangで試してみましたが、どちらもコンパイル時にconstexprを評価することができます。ここ

は私のテストコードです:

#include <cstdint> 
#include <cstddef> 
#include <string> 

class HashedString { 
public: 

//value working only for a 32bit hash 
constexpr static size_t defaultOffset = 2166136261u; 
constexpr static size_t prime = 16777619u; 

/** 
* Compute the hash of a string at compile time using FNV-1a hash 
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80 %93Vo_hash_function 
*/ 
template<std::size_t N> 
constexpr HashedString(const char(&a)[N]) noexcept 
    : mHash(hash(a)) 
#if defined(_DEBUG) 
    , mString(a) 
#endif 
{ 
} 
explicit constexpr HashedString(size_t h) noexcept : mHash(h) {} 

constexpr static size_t hash(const char *const aString, const uint32_t val = defaultOffset) noexcept 
{ 
    return (aString[0] == '\0') ? val : hash(&aString[1], (val^uint32_t(aString[0])) * prime); 
} 

constexpr bool operator==(const HashedString & hs) const { return mHash == hs.mHash; } 
constexpr bool operator==(const size_t & h) const { return mHash == h; } 
constexpr bool operator!=(const HashedString & hs) const { return mHash != hs.mHash; } 
constexpr bool operator!=(const size_t & h) const { return mHash != h; } 
constexpr bool operator<(const HashedString & hs) const { return mHash < hs.mHash; } 

private: 
    const size_t mHash = 0; 
#if defined(_DEBUG) 
    const char* mString = nullptr; 
#endif 
}; 

static_assert(HashedString("FNV Hash Test") == 0xF38B3DB9, "HashedString of 'FNV Hash Test' shoulb be equal to 0xF38B3DB9"); 

int main(int , char**) { 
    constexpr HashedString hs("FNV Hash Test"); 
    return hs == 0xF38B3DB9; 
} 

だから私の質問は次のとおりです。Visual Studioは、コンパイル時に私のconstexprのを計算する方法はありますか?メインの変更(コードの変更、コンパイルフラグ、...)

答えて

1

constexpr auto hash = HashedString::hash("FNV Hash Test"); 
return hash == 0xF38B3DB9; 

または

constexpr HashedString hs("FNV Hash Test"); 
constexpr auto answer = hs == 0xF38B3DB9; 
return answer; 

は、ハッシュは、コンパイル時に計算されるようになります。あなたのコードがそこにあった方法は、コンパイル時にハッシュを計算するコンパイラに対する要求はありませんでした。コンパイラにconstexpr変数を初期化するよう要求することにより、コンパイル時に値を強制的に計算します。メインコードを以下に変更しました:

mov eax,1 
ret 

Booyah! VS2015のSSA最適化のために。

+0

ありがとうございます! – user2576606

関連する問題