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

问题描述 投票:2回答:3

我想投射一个指针pc指向char到点pi指向int

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

是否有任何更简单的方法来执行此演员并使编译器保持沉默?

c++ pointers casting
3个回答
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的指针”类型的prvalue转换为“指向T2”的类型(其中T1T2是对象类型,T2的对齐要求不比T1更严格)并返回其原始类型产生原始指针值。 - 结束说明]

现在,让我们来看看两步转换的每一步。首先,我们有一个static_cast<void*>。根据[conv.ptr]/2(强调我的):

类型为“指向cv T的指针”的prvalue,其中T是一个对象类型,可以转换为“指向cv void的指针”类型的prvalue。此转换不会改变指针值。

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

指向cv-qualified或cv-nonqualified void的指针可用于指向未知类型的对象。这样的指针应该能够保存任何对象指针。 cv void*类型的对象应具有与cv char*相同的表示和对齐要求。

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

类型为“指向cv1 void的指针”的prvalue可以转换为类型为“指向cv2 T的指针”的prvalue,其中T是对象类型,cv2是与cv1相同的cv-qualification,或更高的cv-qualification。如果原始指针值表示存储器中字节的地址A而A不满足T的对齐要求,则未指定结果指针值。否则,如果原始指针值指向对象a,并且存在类型为T(忽略cv-qualification)的对象b,该对象b是指针可互换的,则结果是指向b的指针。否则,转换指针值不变。

我要去哪里?假设pc已经拥有int的地址(根据上面适当转换),然后通过char*int*投射到reinterpret_cast将给你原始int的地址。第一段下的说明同样多,而进一步的引用证明了这一点。如果它不能保持int的地址,那么你正在玩轮盘赌并且很可能会失败。您的程序有未定义的行为。你应该按照芭丝谢芭的建议去写信。


7
投票

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

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

pi = reinterpret_cast<int*>(pc);

6
投票

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

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

不要这样做。永远。

© www.soinside.com 2019 - 2024. All rights reserved.