C++ 为什么我必须重新解释_cast指针?

C++ 为什么我必须重新解释_cast指针?,c++,void-pointers,reinterpret-cast,static-cast,double-pointer,C++,Void Pointers,Reinterpret Cast,Static Cast,Double Pointer,所以这个static\u castcode是完全合法的: int n = 13; void* pn = static_cast<void*>(&n); void** ppn = &pn; 如果我不更改它,我会得到错误: 错误C2440:static\u cast:无法从int**转换为void** 注:指向的类型不相关;转换需要重新解释转换、C样式转换或函数样式转换 所以我认为问题是“类型是不相关的”。然而,我仍然不明白,如果从int*到void*是可以的,那么它们

所以这个
static\u cast
code是完全合法的:

int n = 13;
void* pn = static_cast<void*>(&n);
void** ppn = &pn;
如果我不更改它,我会得到错误:

错误C2440:
static\u cast
:无法从
int**
转换为
void**
注:指向的类型不相关;转换需要重新解释转换、C样式转换或函数样式转换


所以我认为问题是“类型是不相关的”。然而,我仍然不明白,如果从
int*
void*
是可以的,那么它们怎么会与
int**
void**
无关呢?

int
void
没有任何关系。这同样适用于
int**
void**
,因此不能使用
static\u cast
转换它们

void*
然而,它是特殊的。任何数据指针类型(包括
int*
)都可以
static\u cast
转换为
void*
并返回,尽管没有与
void
相关的类型(更进一步地说,转换为
void*
不需要转换,因为它是隐式的)
int*
没有此属性,也没有
void**
void*
之外的任何其他指针


已授予
void*
的额外自由也有额外的限制
void*
不能间接,也不能与指针算法一起使用。这些限制之所以可能,是因为永远不可能存在类型为
void
的对象。或者从相反的角度来看,
void
的对象由于这些限制而不存在

void**
不能被赋予这些自由,因为它不能被赋予相同的限制。不能给它这些限制,因为
void*
对象确实存在,并且它们需要存在。如果我们不能间接或迭代
void**
,那么我们就不能使用
void*
的数组

void* pn = static_cast<void*>(&n);
这意味着
pn
存储指向某个对象类型的指针;程序员负责知道对象类型是什么。要回退,您需要一个
静态\u cast

int *pi = static_cast<int*>(pn);

由于类型不匹配,与
void**
不同的类型无法分配给
void**
取消引用
void**
的结果必须是
void*
对象

为什么第二个代码段被删除?您可以看到
&foo
作为指向
int*
的指针,而
bar
是指向
void*
的指针。这两种类型非常不同。这是额外的间接级别造成了整个差异。请注意,甚至不能保证
sizeof(int*)
sizeof(void*)
是same@JonathanMee:如果指针没有对齐要求(
void*
char*
),则可以满足往返要求大于具有对齐要求的指针(包括
int*
)。
static\u cast
甚至不是显式转换,而是显式完成的隐式转换,指针类型之间的
reinterpret\u cast
实际上被定义为具有与转换为
void*
然后是
static\u cast
相同的结果。
void *pn = &n;
int *pi = static_cast<int*>(pn);
float *f = &i; // ill-formed