为什么我可以将 void* static_cast 到 int* 而不是 int*&?
Why can I static_cast void* to int* but not to int*&?
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;
的原因。
当然,在许多实现(int
和long
的大小,表示和对齐(上,它可以工作。但是,对于所有实现,铸造有效的规则大多都是相同的,显然,这在int
和long
具有不同尺寸的平台上永远无法使用,这意味着不可能允许在这些平台上访问另一个。/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));
,则此优化将无效。由于这种优化已被证明有用,因此规则不太可能更改。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 如何理解C++标准N3337中的expr.const.cast子句8
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 为什么选择 g++ 给予者:"error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]"
- 是否可以使用gcc 3.3版修复与int*cast相关的Sun Solaris OS 5.8分段故障
- int cast 和 int& cast 之间的区别
- "invalid cast from type 'const myClass' to type 'int'",如何使其有效?
- 编译程序时出错C++:"error: cast from ‘double*’ to ‘int’ loses precision"
- Cast int to void* and void* to int for TMemoryStream->WriteBuffer (C++Builder XE7)