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;
但为什么不允许第一个允许?
在回答“因为标准是这样说”之前,为什么标准是这样说的?第一种方法有点危险吗?或者只是一个疏忽?
答案 0 :(得分:3)
不允许出于int i; static_cast<long &>(l) = 3L;
不允许的原因。
当然,在很多实现中(int
和long
具有相同的大小,表示和对齐方式),可以工作。但是对于所有实现,强制转换的规则大多是相同的,显然这在int
和long
具有不同大小的平台上永远不会起作用,这意味着它不可能被允许在这些平台上访问另一个。
从历史上看,已经有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));
,则此优化将无效。因为这种优化已被证明是有用的,所以规则不太可能改变。