1.为什么?
像这样的代码过去常常起作用,它应该是什么意思。 编译器是否允许 (通过规范)使其成为错误?
我知道它正在失去精确度,我会很高兴收到警告。 但它仍然有一个明确定义的语义(至少对于未定义的缩小版本定义)并且用户可能想要这样做。
2.解决方法
我有遗留代码,我不想重构太多,因为它相当棘手并且已经调试过。 它做了两件事:
那么最具侵入性的合适解决方法是什么? 已知代码在使用不会产生此错误的编译器编译时工作,所以我真的想要进行操作,而不是更改它。
笔记:
void *x; int y; union U { void *p; int i; } u;
C ++,5.2.10:
4 – 指针可以显式转换为足以容纳它的任何整数类型。 […]
C,6.3.2.3:
6 – 任何指针类型都可以转换为整数类型。 […]如果结果无法以整数类型表示,则行为未定义。 […]
因此,如果int
是32位且void *
是64位,那么(int) p
是非法的; C ++编译器是正确的给你一个错误,而C编译器可能会在转换时给出错误或发出一个具有未定义行为的程序。
您应该编写,添加一个转换:
(int) (intptr_t) p
或者,使用C ++语法,
static_cast(reinterpret_cast(p))
如果要转换为无符号整数类型,请通过uintptr_t
而不是intptr_t
。
这是一个很难解决的“一般”,因为“松散精度”表示你的指针大于你试图存储它的类型。在你的脑海中可能很“好”,但是编译器是关心的您将把int值恢复为指针,现在已经丢失了高32位(假设我们正在讨论32位int和64位指针 – 还有其他可能的组合)。
uintptr_t
与系统上的指针大小兼容,因此通常可以通过以下方式克服实际错误:
int x = static_cast(reinterpret_cast(some_ptr));
这将首先从指针强制大整数,然后将大整数强制转换为较小的类型。
回答C
将指针转换为整数是实现定义的。 你的问题是,你所谈论的代码似乎永远不正确。 并且可能只适用于int
和指针都是32位的古代架构。
唯一应该转换而没有丢失的类型是[u]intptr_t
,如果它们存在于平台上(通常它们就是这样)。 这种uintptr_t
哪一部分适合用于你的哈希函数很难说,你不应该对此做出任何假设。 我会选择类似的东西
uintptr_t n = (uintptr_t)x;
然后
((n >> 32) ^ n) & UINT32_MAX
这可以在32位拱上进行优化,并且可以为您提供64位拱上所有其他位的跟踪。
对于C ++,基本上应该适用相同的,只需要转换为reinterpret_cast
。
以上就是c/c++开发分享为什么“从’X *’转换为’Y’会失去精度”这是一个很难的错误,什么是遗留代码的合适修复相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545881.html