“整数常数溢出”; constexpr中的警告 [英] "integer constant overflow" warning in constexpr
问题描述
我试图找到一个与constexpr兼容的哈希函数,以用于在编译时对字符串进行哈希处理。字符串的数量确实很少(小于10),而且我需要单独检查冲突,因此该算法可能远非完美。我在互联网上的某个地方找到了以下版本的FNV1A:
I'm trying to find a constexpr compatible hash function to use for hashing strings in compile-time. The number of strings are really small (<10) and I have a separate check for collisions, so the algorithm can be far from perfect. I found the following version of FNV1A somewhere on the internet:
static constexpr unsigned int Fnv1aBasis = 0x811C9DC5;
static constexpr unsigned int Fnv1aPrime = 0x01000193;
constexpr unsigned int hashFnv1a(const char *s, unsigned int h = Fnv1aBasis)
{
return !*s ? h : hashFnv1a(s + 1, (h ^ *s) * Fnv1aPrime);
}
但是当我在MSVS 2015中进行编译时,会收到以下警告:
But when I compile this in MSVS 2015 I get the following warning:
warning C4307: '*': integral constant overflow
由于函数中只有一个乘法,因此我认为警告来自(h ^ * s)* Fnv1aPrime
。这是有道理的,因为将 0x811C9DC5
( Fnv1aBasis
)乘以几乎任何东西都会导致32位整数溢出。
Since there's only one multiplication in the function I would assume the warning comes from (h ^ *s) * Fnv1aPrime
. It makes sense since multiplying 0x811C9DC5
(Fnv1aBasis
) with just about anything will make a 32-bit integer overflow.
有什么办法可以解决此问题?我已经尝试了一些其他的用于对字符串进行哈希处理的constexpr函数,但它们都具有相同的问题。
Is there any way to work around this? I've tried a couple of other constexpr functions I've found for hashing strings, but all of them have the same issue.
推荐答案
您可以明确地强制转换为 unsigned long long
并返回,如下所示:
You can explicitly cast to unsigned long long
and back, as follows:
constexpr unsigned int hashFnv1b(const char *s, unsigned int h = Fnv1aBasis)
{
return !*s
? h
: hashFnv1b(
s + 1,
static_cast<unsigned int>(
(h ^ *s) * static_cast<unsigned long long>(Fnv1aPrime)));
}
此在我的现场演示中停止警告(第20行触发它,而第21行则不触发)。
This stops the warning in my live demo (line 20 triggers it, line 21 does not).
这篇关于“整数常数溢出”; constexpr中的警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!