C++ 为什么我可以将void*强制转换为int*而不是int*&;?
API使用C++ 为什么我可以将void*强制转换为int*而不是int*&;?,c++,pointers,casting,C++,Pointers,Casting,API使用void*存储非类型指针偏移量。这有点老套,不过没关系 为了表达我的偏移量算法,我试着做这样的事情 int main () { void * foo; foo = static_cast <int *> (nullptr) + 100; static_cast <int * &> (foo) += 100; } 解决方法很简单: foo = static_cast <int *> (foo) + 100; fo
void*
存储非类型指针偏移量。这有点老套,不过没关系
为了表达我的偏移量算法,我试着做这样的事情
int main ()
{
void * foo;
foo = static_cast <int *> (nullptr) + 100;
static_cast <int * &> (foo) += 100;
}
解决方法很简单:
foo = static_cast <int *> (foo) + 100;
foo=static_cast(foo)+100;
但是为什么不允许第一个呢
在回答“因为标准这么说”之前,标准为什么这么说?第一种方法危险吗?还是仅仅是疏忽?这是不允许的,原因与
inti;静态铸造(l)=3L代码>是不允许的
当然,在很多实现中(其中int
和long
具有相同的大小、表示和对齐方式),它都可以工作。但是强制转换的有效规则对于所有实现都是相同的,显然这在int
和long
具有不同大小的平台上是不可能的,这意味着不可能允许在这些平台上访问一个
历史上,有一些实现在void*
和int*
上有不同的表示
后来,在标准规定像访问int*
一样访问void*
是无效的之后,实现也开始优化,假设有效的程序不会这样做:
void *f (void **ppv, int **ppi) {
void *result = *ppv;
*ppi = nullptr;
return result;
}
允许实现对此进行优化,以
void *f (void **ppv, int **ppi) {
*ppi = nullptr;
return *ppv;
}
而这样的优化,当它们减少代码大小或提高效率时,如今已经司空见惯了。如果f
被允许称为void*pv=&pv;f(pv和静态浇铸(pv))代码>,此优化将无效。由于这种优化被证明是有用的,因此规则不太可能改变。理论上,不能保证void*
和int*
具有相同的大小。作为左值,它们可能不兼容。虽然这在实践中是不可能的。@lilistence:在实践中,int*
所需的位比void*
少,所以虽然这可能很少见,但它们实际上大小不同(与在int*
中有两个未使用/填充位相比)也不是不可能的。最后一个例子很有说服力,以前我认为这些区别只是理论上的。通过对叮当声的测试,此优化甚至针对-O1
。回答得很好,谢谢。但是为什么我的x=static\u cast(x)+n
fix不被禁止?@spraff这就像inti=3;i=静态压力(i)+1L代码>。这里没有比特的重新解释,只有值的转换。即使void*
和int*
具有不同的表示形式,那么static_cast(x)
将更改表示形式,n
将被添加,隐式转换回void*
将更改表示形式。
void *f (void **ppv, int **ppi) {
*ppi = nullptr;
return *ppv;
}