c/c++开发分享为什么“从’X *’转换为’Y’会失去精度”这是一个很难的错误,什么是遗留代码的合适修复

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(x)

      以上就是c/c++开发分享为什么“从’X *’转换为’Y’会失去精度”这是一个很难的错误,什么是遗留代码的合适修复相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(猴子技术宅)。

      本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/545881.html

      发表评论

      电子邮件地址不会被公开。 必填项已用*标注