【发布时间】:2014-07-15 23:01:16
【问题描述】:
我正在处理new hashing system。部分实现需要将指向某个内存位置的指针传递给具有如下签名的算法函子:
void
operator()(void const* key, std::size_t len) noexcept
{
unsigned char const* p = static_cast<unsigned char const*>(key);
unsigned char const* const e = p + len;
std::size_t h = 14695981039346656037u;
for (; p < e; ++p)
h = (h ^ *p) * 1099511628211u;
return h;
}
在对基本类型进行操作时,我只需传入一个指向类型开头和大小的指针:
template <class HASHALG>
void hash_append(HASHALG& hashAlg, char const input)
{
hashAlg(&input, sizeof(input));
}
我问是否对布尔值的二进制表示有任何保证,是因为我想知道以下是否会按预期运行:
template <class HASHALG>
void hash_append(HASHALG& hashAlg, bool const input)
{
hashAlg(&input, sizeof(input));
}
我担心可能发生的是编译器可能会选择真正的布尔值可以具有任何非零整数表示。即:
10110010 => true
10101010 => true
10100010 => true
00100010 => true
01100110 => true
00000000 => false
如果是这种情况,那么作为字节的散列是无效的,因为相同的值 (true) 可以产生许多不同的散列。
我搜索了标准,我只能找到以下两个部分:
(3.9.1.7) bool、char、char16_t、char32_t、wchar_t 类型以及有符号和无符号整数类型统称为整数类型。整数类型的同义词是整数类型。整数类型的表示应使用纯二进制计数系统定义值。
(4.5.6) bool 类型的纯右值可以转换为 int 类型的纯右值,false 变为 0,true 变为 1。
所以我知道一个 int 将有一个整数表示,并且我知道当转换为一个 int 时,它将是 1 或 0,但是标准是否保证它会有一个固定的表示?在大多数情况下,编译器似乎只是实现了这个:
true => 00000001
false => 00000000
如果不能保证这将是表示,我不想被一些模糊的边缘情况烧毁。
【问题讨论】:
-
[expr.sizeof] Note: in particular, sizeof(bool), sizeof(char16_t), sizeof(char32_t), and sizeof(wchar_t) are implementation-defined. -
@user657267:谢谢,但是,实现定义的大小不是问题。散列值在机器之间是不同的,因此散列更多或更少的字节是可以的,只要其一致。我更关心
true在那些1、2、527 中的表示是否总是相同的字节数。