为什么我可以static_cast void * to int *但不能int *&?

时间:2018-02-18 18:36:35

标签: c++ pointers casting

API使用void*来存储无类型指针偏移量。这有点hacky,但没关系。

为了表达我的偏移算术,我试着做这样的事情

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;

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

在回答“因为标准是这样说”之前,为什么标准是这样说的?第一种方法有点危险吗?或者只是一个疏忽?

1 个答案:

答案 0 :(得分:3)

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

当然,在很多实现中(intlong具有相同的大小,表示和对齐方式),可以工作。但是对于所有实现,强制转换的规则大多是相同的,显然这在intlong具有不同大小的平台上永远不会起作用,这意味着它不可能被允许在这些平台上访问另一个。

从历史上看,已经有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));,则此优化将无效。因为这种优化已被证明是有用的,所以规则不太可能改变。