Reinterpret_cast转换链的正确性 [英] Reinterpret_cast conversion chain correctness

查看:97
本文介绍了Reinterpret_cast转换链的正确性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据类型别名规则,我假设:



1)将 uint64_t * 直接转换为 uint32_t * - 不正确



2)转换链确定

uint64_t * - > unsigned char * - > uint32_t *

uint64_t * - > void * - > uint32_t *



我是否正确理解规则?



我总是喜欢使用 union 来防止任何可能的ptr。转换问题(可能导致数据损坏),但并不总是可能(和好)解决方案。



我尝试过:



类型别名规则: reinterpret_cast转换 - cppreference.com [ ^ ]

According to the type aliasing rules i assume that:

1) direct conversion of uint64_t* to uint32_t* - is incorrect

2) conversion chains is OK
uint64_t* -> unsigned char* -> uint32_t*
uint64_t* -> void* -> uint32_t*

Am i understanding the rules correctly or not?

I'm always prefer to use unions instead, to prevent any possible ptr. conversion problems (which can cause data corruption), but it is not always possible (and good) solution.

What I have tried:

Type aliasing rules: reinterpret_cast conversion - cppreference.com[^]

推荐答案

假设你的意思是 uint 64_t uint 32_t ,它没有什么不同。真正的问题是您的代码如何正确处理数值。您需要了解转换不会转换任何内容。所有这一切都告诉编译器,我在做一些稍微危险的事情,但我知道我在做什么。
Assuming you actually mean uint64_t and uint32_t, it makes no real difference. The real issue is how your code will handle the numeric values correctly. You need to understand that casting does not convert anything. All it does is tell the compiler, "I am doing something slightly dangerous here, but I know what I am doing".


首先,你需要了解这种类型的演员是什么确实:它重新解析对象,逐位获取源对象的所有数据。要理解的第二件事是:所有指针对象都具有相同的大小。



您可以随时在所有指针之间进行转换,并且转换本身将始终有效,但有效性此操作取决于您将如何处理指针指向的内存区域。一般情况下,它可以让您访问指向原始指针的对象后面的某些区域。这种访问的结果可能不同。在某些情况下,你可以得到垃圾。在其他情况下,您可以访问为原始对象保留的内存区域后面的对象,因此您可以写入此区域(请注意您的指针不是常量),损坏这些对象,导致一般保护错误异常,任何事情。 />


注意即使没有强制转换,所有这些麻烦都会发生,如果由于其他原因,你的指针指向某个错误的内存区域。



让我们看看:



First of all, you need to understand what this type of cast does: it reinteprets the object taking all data of a source object bit by bit. Second thing to understand is: all pointer objects are of the same size.

You can always convert between all pointers, and the cast itself will always work, but the validity of this operation depends on what you are going to do with the area of memory pointed by the pointer. In general case, it can give you access to some area behind the object pointed to be the original pointer. The result of such access can be different. In some cases, you can get just garbage. In other cases, you may access the object behind the memory area reserved for the original object, so you can write to this area (note that your pointers are not constant), corrupt those objects, cause General Protection Fault exception, anything.

Note all of those kind of trouble can happen even without the cast, if, by some other reason, your pointer points to some wrong area of memory.

Let's see:

  1. uint64_t * to uint32_t *

    没问题,除了丢失大于最大32位整数的64位整数的部分数据,所以你可能得到错误的数据。 (对于负面数据,情况相同,只是更复杂;请参阅两个补充 - 维基百科,免费百科全书。)

    你不能伤害其他数据,因为新的指针,案例的结果,使你可以访问比你更小的内存区域。

  2. uint64_t * - > unsigned char * - > uint32_t *

    uint64_t * - > void * - > uint32_t *




    这取决于你在做什么。如果你没有触摸中间指针对象( unsigned char * void * ),只需再次投射它,它没有区别。这个中间演员简直是多余的,完全没有意义。除非再次强制转换,否则无法使用void指针直接访问任何内容。至于指向一个字符的指针,它指向的内存区域甚至比指向 uint32 的指针更少,所以你不能使用它来破坏任何东西,这是我在第1项中解释的原因。

  1. uint64_t* to uint32_t*
    No problem, except loosing part of data for 64-bit integers which are bigger than maximum 32-bit integers, so you can get wrong data. (With negative data, the situation is the same, just more complicated; please see Two's complement — Wikipedia, the free encyclopedia.)
    You cannot harm other data, because the new pointer, result of the case, gives you access to smaller area of memory than.
  2. uint64_t* -> unsigned char* -> uint32_t*
    uint64_t* -> void* -> uint32_t*


    It depends what you are doing. If you don't touch intermediate pointer objects (unsigned char*, void*), just cast it again, it makes no difference. This intermediate cast is simply redundant, makes no sense at all. You cannot access anything directly with void pointer unless you cast it again. As to pointer to a character, it points to even less area of memory than pointer to uint32, so you cannot corrupt anything using it, by the reason I explained in item #1.



请注意,我从未提及所有这些操作的目的,所以我不确定任何事情都没有意义。关于这些操作的正确性的问题没有任何预定义;这一切都取决于你试图实现的目标以及你将如何处理案件的结果。最重要的是你必须了解到底发生了什么。



-SA


这篇关于Reinterpret_cast转换链的正确性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆