gpt4 book ai didi

c++ - 通过 void* 进行转换,而不是使用 reinterpret_cast

转载 作者:IT老高 更新时间:2023-10-28 12:32:30 24 4
gpt4 key购买 nike

我在看书,发现reinterpret_cast不应该直接使用,而是结合static_cast强制转换为void*:

T1 * p1=...
void *pv=p1;
T2 * p2= static_cast<T2*>(pv);

代替:

T1 * p1=...
T2 * p2= reinterpret_cast<T2*>(p1);

但是,我找不到解释为什么这比直接转换更好。如果有人能给我解释或指出答案,我将不胜感激。

提前致谢

附言我知道 reinterpret_cast 是用来做什么的,但我从来没有见过以这种方式使用的

最佳答案

对于允许进行这种强制转换的类型(例如,如果 T1 是 POD 类型且 T2unsigned char),该方法static_cast 由标准明确定义。

另一方面,reinterpret_cast 完全是实现定义的——唯一能保证你可以将指针类型转换为任何其他指针类型,然后再返回,然后你会得到原始值;而且,您可以将指针类型转换为足够大的整数类型以保存指针值(取决于实现,并且根本不需要存在),然后将其转换回来,您将获得原始值。

更具体地说,我将仅引用标准的相关部分,突出显示重要部分:

5.2.10[expr.reinterpret.cast]:

The mapping performed by reinterpret_cast is implementation-defined. [Note: it might, or might not, produce a representation different from the original value.] ... A pointer to an object can be explicitly converted to a pointer to an object of different type.) Except that converting an rvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

所以是这样的:

struct pod_t { int x; };
pod_t pod;
char* p = reinterpret_cast<char*>(&pod);
memset(p, 0, sizeof pod);

实际上未指定。

解释为什么 static_cast 工作有点棘手。这是上面重写的代码以使用 static_cast 我相信它可以保证始终按照标准的预期工作:

struct pod_t { int x; };
pod_t pod;
char* p = static_cast<char*>(static_cast<void*>(&pod));
memset(p, 0, sizeof pod);

再次,让我引用标准中的部分,这些部分共同使我得出结论,上述内容应该是可移植的:

3.9[basic.types]:

For any object (other than a base-class subobject) of POD type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char. If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value.

The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T).

3.9.2[basic.compound]:

Objects of cv-qualified (3.9.3) or cv-unqualified type void* (pointer to void), can be used to point to objects of unknown type. A void* shall be able to hold any object pointer. A cv-qualified or cv-unqualified (3.9.3) void* shall have the same representation and alignment requirements as a cv-qualified or cv-unqualified char*.

3.10[basic.lval]:

If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined):

  • ...
  • a char or unsigned char type.

4.10[conv.ptr]:

An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.” The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject).

5.2.9[expr.static.cast]:

The inverse of any standard conversion sequence (clause 4), other than the lvalue-to-rvalue (4.1), array-topointer (4.2), function-to-pointer (4.3), and boolean (4.12) conversions, can be performed explicitly using static_cast.

[编辑]另一方面,我们有这个 gem :

9.2[class.mem]/17:

A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]

这似乎暗示指针之间的 reinterpret_cast 以某种方式暗示“相同的地址”。去搞清楚。

关于c++ - 通过 void* 进行转换,而不是使用 reinterpret_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1863069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com