为什么我可以将 void* static_cast 到 int* 而不是 int*&?

Why can I static_cast void* to int* but not to int*&?

本文关键字:int cast 我可以 void static 为什么      更新时间:2023-10-16

API使用void*存储未型的指针偏移。有点骇客,但是好的。

要表达我的偏移算术,我尝试做类似的事情

int main ()
{
    void * foo;
    foo = static_cast <int *> (nullptr) + 100;
    static_cast <int * &> (foo) += 100;
}

最后一行无法编译(GCC(

x.cpp:7:28: error: invalid static_cast from type ‘void*’ to type ‘int*&’

修复很简单:

foo = static_cast <int *> (foo) + 100;

但是为什么不允许第一个?

在回答"因为标准这样说"之前,为什么标准这样说?第一种方法是否危险?还是只是一个疏忽?

不允许使用int i; static_cast<long &>(l) = 3L;的原因。

当然,在许多实现(intlong的大小,表示和对齐(上,它可以工作。但是,对于所有实现,铸造有效的规则大多都是相同的,显然,这在intlong具有不同尺寸的平台上永远无法使用,这意味着不可能允许在这些平台上访问另一个。/p>

从历史上看,void *int *具有不同的表示。

稍后,在标准表明访问void *的范围之后,就好像它是int *无效,实现还开始优化有效程序不执行此操作的假设:

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, &static_cast<int*&>(pv));,则此优化将无效。由于这种优化已被证明有用,因此规则不太可能更改。