GCC / Clang constexpr优化给出不同的结果

时间:2018-07-27 15:25:42

标签: string gcc hash clang constexpr

我正在寻找一种创建string_id的方法,该字符串将在调试时为字符串,而在发布时为哈希,而无需用户做过多的工作(即,不提供id和字符串)。我已经按照互联网的建议实施了fnv1a,这就是我得到的:

#ifdef HASH_STRING_IDS
#include <cstdint>
#define StringId std::uint32_t
constexpr StringId fnv1a(char const* s, std::size_t count)
{
    return ((count ? fnv1a(s, count - 1) : 2166136261u) ^ s[count]) * 16777619u;
}

constexpr StringId operator"" _id(char const* s, std::size_t count)
{
    return fnv1a(s, count);
}

#else // HASH_STRING_IDS
#include <string>
#define StringId std::string


StringId operator"" _id(char const* s, std::size_t count)
{
    return{ s, count };
}

#endif // HASH_STRING_IDS

问题是gcc很好,它将在编译时评估id,但是clang和MSVC都不会(即使在最高级别的优化下,哈希也要在执行时计算);的示例:

#ifdef HASH_STRING_IDS
std::uint32_t doStuff(StringId id)
{
    return id * 7;
}
#else // HASH_STRING_IDS
std::uint32_t doStuff(StringId id)
{
    return id.size() * 7;
}
#endif // HASH_STRING_IDS

int main()
{
    return doStuff("test"_id);
}

有什么原因吗?

我遇到的另一个问题是我无法检测到碰撞,并且希望如此。有什么聪明的方法可以做到这一点吗?

感谢您的回复:)

0 个答案:

没有答案