如何将指向char的指针强制转换为指向int的指针

时间:2017-12-28 09:49:20

标签: c++ pointers casting

我想将一个指向pi的指针指向一个点char *pc; int *pi; pi = (int*)pc // compiler complaint about old-style cast pi = static_cast<int *>(static_cast<void *>(pc)) // no complaint any more but too complex ,指向int

{{1}}

有没有更简单的方法来执行此转换并使编译器静音?

3 个答案:

答案 0 :(得分:7)

如果你真的需要这样做,那么reinterpret_cast就是你的朋友:

char *pc = 0;
int *pi = 0;

pi = reinterpret_cast<int*>(pc);

答案 1 :(得分:6)

一般来说,转换char*指向int*指针的行为是 undefined 。取消引用这样的指针会导致您进一步麻烦,因为您将破坏严格别名规则。请注意,C ++标准不要求sizeof(char*)sizeof(int*)相同。

(请注意,如果unsigned char*指针实际指向int*,则将unsigned char*指针转换为int是明确定义的。

不要这样做。如初。

答案 2 :(得分:1)

我想在@Bathsheba's post下来回休息。所以这里是关于你正在做什么的更精细细节的答案。

@Sean already suggestedreinterpret_cast代替了你的指针。这相当于你的第二个演员阵容。它在[expr.reinterpret.cast]/7中说得很多:

  

可以将对象指针显式转换为对象指针   不同的类型。当对象指针类型的prvalue v为时   转换为对象指针类型“指向cv T的指针”,结果是   static_­cast<cv T*>(static_­cast<cv void*>(v))。 [注意:转换一个   类型为“T1”的类型为“指向T2”的类型的prvalue(其中T1   和T2是对象类型,T2的对齐要求是   没有比T1更严格的并且回到它的原始类型产生   原始指针值。 - 结束说明]

现在,让我们来看看两步转换的每一步。首先我们有一个static_cast<void*>。根据{{​​3}}(强调我的):

  

类型为“指向cv T的指针”的prvalue,其中T是对象类型,可以是   转换为“指向cv void的指针”的prvalue。 指针值   此转换未更改

第一次转换不会对地址进行任何更改。然后它也在[conv.ptr]/2中说:

  

指向cv-qualified或cv-unqualified void的指针可用于指向   对于未知类型的对象。这样的指针应该可以容纳任何指针   对象指针。 cv void*类型的对象应具有相同的对象   表示和对齐要求为cv char*

因此char*可以存储void*可能存储的任何地址。现在,这并不意味着从void*char*的转换是值保留,只是它们可以表示相同的值。现在,假设一个非常有限的用例,这足以保证。但是[basic.compound]/5还有更多内容:

  

“指向cv1 void的指针”类型的prvalue可以转换为prvalue   类型为“指向cv2 T的指针”,其中T是对象类型,cv2是   与cv1相同的cv资格,或更高的cv资格。如果   原始指针值表示一个字节的地址A.   内存和A不满足T的对齐要求,那么   结果指针值未指定。否则,如果是原件   指针值指向一个对象a,并且有一个类型的对象b   T(忽略cv资格),指针可与a互换,   结果是指向b的指针。 否则,指针值为   转换未改变

我要去哪里?假设pc已经拥有int的地址(根据上述内容进行了适当转换),那么char*通过int*投放到reinterpret_cast会给你原始int的地址。第一段下的说明同样多,而进一步的引用证明了这一点。如果它不包含int的地址,则表示您正在玩轮盘赌而且可能会丢失。您的程序有未定义的行为。你应该遵循芭丝谢芭对这封信的建议。