为什么我不能reinterpret_cast的UINT为int?(Why can't I r

2019-07-19 01:26发布

这是我想做的事:

const int64_t randomIntNumber = reinterpret_cast<int64_t> (randomUintNumber);

其中randomUintNumber的类型为uint64_t

错误的是(2010 MSVC):

错误C2440:“的reinterpret_cast”:不能从“const的uint64_t中”转换到“的int64_t” 1>转换是有效的标准转换,这可以隐式或通过使用的static_cast,C样式转换或函数样式转换来执行

为什么不把它编译? 这两种类型具有相同的位长,是不是它的目的是什么reinterpret_cast的呢?

Answer 1:

因为这不是reinterpret_cast是。 所有与允许转换reinterpret_cast涉及指针或引用,与整数或枚举类型可以例外reinterpret_cast本身。 这是在标准中定义的所有, [expr.reinterpret.cast]

我不能确定你想在这里实现什么,但如果你想randomIntNumber具有相同的价值randomUintNumber ,然后做

const int64_t randomIntNumber = randomUintNumber;

如果导致编译器警告,或者如果你只是想更明确的,则:

const int64_t randomIntNumber = static_cast<int64_t>(randomUintNumber);

铸造的结果具有相同的值作为输入,如果randomUintNumber小于2 63。 否则,结果是实现定义的,但我希望所有已知的实现具有int64_t将定义它做的显而易见的事情:结果是相当于输入模2 64。


如果你想randomIntNumber具有相同的位模式为randomUintNumber ,那么你可以这样做:

int64_t tmp;
std::memcpy(&tmp, &randomUintNumber, sizeof(tmp));
const int64_t randomIntNumber = tmp;

由于int64_t是保证使用二进制补码表示,你会希望实现定义static_cast有相同的结果,因为这对于超出范围的值uint64_t 。 但它不是标准的AFAIK实际上保证。

即使randomUintNumber是一个编译时间常数,可惜这里randomIntNumber不是编译时间常数。 不过,如何“随机”是一个编译时间常数? ;-)

如果您需要解决的是,和你不信任的实施是明智的有关转换超出范围的无符号值符号类型,则是这样的:

const int64_t randomIntNumber = 
    randomUintNumber <= INT64_MAX ? 
        (int64_t) randomUintNumber :
        (int64_t) (randomUintNumber - INT64_MAX - 1) + INT64_MIN;

现在,我赞成编写真正便携的代码,其中可能的,但即使如此,我认为这近乎偏执。


顺便说一句,你也许会这样写:

const int64_t randomIntNumber = reinterpret_cast<int64_t&>(randomUintNumber);

或等价:

const int64_t randomIntNumber = *reinterpret_cast<int64_t*>(&randomUintNumber);

这倒不保证工作,因为尽管他们存在int64_tuint64_t都保证有符号类型和无符号类型的大小相同,但实际上并没有保证是一个标准的整数的符号和无符号版本类型。 因此,它是实现特定的代码是否违反严格别名。 违反严格别名代码未定义的行为。 以下违反严格走样,并确定提供的位模式randomUintNumber是一个值的有效表示long long

unsigned long long x = 0;
const long long y = reinterpret_cast<long long &>(x);

因此,在实现中int64_tuint64_t是类型定义long longunsigned long long ,那么我reinterpret_cast是OK。 并与外的范围的值符号类型实现定义的转换,你会期望 ,对于实现做明智的做法是让他们相应的有符号/无符号类型。 所以喜欢static_cast和隐式转换,你希望它在任何合理的实施工作,但它实际上并没有保证。



Answer 2:

使用static_cast在这些情况下。 我想语言设计者在其所有的智慧,决定了它不被认为是“不安全足够的”保证一个reinterpret_cast



Answer 3:

不它不是。 reinterpret_cast大多旨在重新解释存储的现有比特作为不同类型的比它。 很多这些的解释是依赖于实现,标准列出了具体的(相当长在这里引用)的东西,可以用做列表reinterpret_cast (主要是不同的指针/引用类型之间铸造),但是他说:

没有其他的转换可以明确使用的reinterpret_cast进行。

在你的情况,你可能想的类型转换,而不是现有的存储的重新解释。 使用static_cast用于这一目的。



Answer 4:

从C ++ 11标准(N3376)5.2.10.1:

可以明确使用的reinterpret_cast进行转换如下表所示。 没有其他的转换可以明确使用的reinterpret_cast进行。

如果类型是相同的,从整体式到允许的积分类型的唯一转换是逸岸。

其他涉及指针。



Answer 5:

reinterpret_cast用于重新解释对象的存储作为不同的对象。 如果你不想去通过规范的写法,你可以找到所有reinterpret_cast可以做这里 。 一般来说,你可以记得你有一个指针类型的工作。

所以,如果你真的想重新诠释用于您的位uint64_t作为int64_t ,然后执行以下操作:

int64_t randomIntNumber = reinterpret_cast<int64_t&> (randomUintNumber);

但是,如果你只是想转换对象,保持其价值,如果可能的...只是做编译器提出什么,使用static_cast代替。



Answer 6:

为什么不把它编译?

因为无论类型是一个指针。

这两种类型的具有相同的比特长度,

为什么会是怎么回事? 如果他们三分球,也许会的问题,他们指出,同样大小的东西,但他们没有指针。

是不是有什么的reinterpret_cast是为?

不, reinterpret_cast是指针类型转换。 你可以做你想做的通过将一个&演员和一个内*外面。 这就是重新解释投是。



文章来源: Why can't I reinterpret_cast uint to int?