为什么不能static_cast双虚空指针?
Why can't static_cast a double void pointer?
考虑以下代码段:
void **v_dptr(nullptr);
int **i_dptr = static_cast<int**>(v_dptr);
上面的示例产生以下编译错误:
static_cast from 'void **' to 'int **' is not allowed
现场演示
我知道将void
指针转换为任何其他指针类型的正确方法是使用 static_cast
.但是,不能将双void
指针static_cast
到其他类型的另一个双指针。
问:
- 为什么我们不能
static_cast
双void
指针? - 投双
void
指针的正确方法是什么?
当你有一个void*
并将其转换为int*
时,可能会也可能不会有一些数学/宽度调整来创建正确类型的实例,static_cast<>
将准备这样做。 当您只有一个指向void*
的指针并且想要一个指向int*
的指针时,static_cast<>
对指向的void*
对象没有写入访问权限;调整它以确保它是一个有效的int*
这样static_cast<>
可以成功并返回一个真正可用于访问有效int*
的指针是不自由的。 虽然在某些架构上这可能无关紧要,但如果标准允许这样做,那么代码在移植时可能会中断。 (请记住,期望static_cast<>
为它使用static_cast<int*>(the_void_ptr)
初始化的某个地方int*
安排一些额外的内存是不合理的 - 这不仅会产生意外的开销,而且它需要在线程特定的内存中或动态分配并以某种方式释放,并且实际上最终比较指针值的所有代码都会中断。
如果你想强迫这个问题,并向编译器承诺两种类型的宽度是相同的,不需要数学调整等 - 那么你可以使用reinterpret_cast<>
并操纵它,清楚地表明你正在接受未定义行为的风险。
void*
的特殊之处在于它可以指向任何东西。它是"指向未指定类型的指针"。因此,对于某种类型的T
,从void*
到T*
的转换是一种"正常"操作,static_cast
可以支持的操作。实际上,这样的转换说:"指针不知道它指向什么,但我知道它:它指向一个T
。
void**
在这种方式上并不特别。它只能指向一件事,指向void*
。将void**
转换为int**
会说一些不同的东西:"指针声称它指向void*
,但我想将其视为指向int*
的指针。如果你想把一件事当作另一件事,你想重新解释原作——所以使用 reinterpret_cast
.
这是一个XY问题。根据情况,可以在没有reinterpret_cast
的情况下解决。如果您知道void**
指针实际上指向指向 int
的指针,则可以安全地执行此操作:
int* iptr = static_cast<int*>(*v_dptr);
除非你真的需要在代码中int**
。如果需要,您可以执行以下操作:
int** i_dptr = &iptr;
但请注意,它会指向一个局部变量iptr
当超出范围时,该变量将被销毁。
Q1 有很好的答案,Q2 的答案很大程度上取决于意图。如果void **v_dptr
旨在成为指向"泛型"void*
的指针,您知道该实际上是一个int*
并且您希望相应地强制转换,则以下内容可能是您想要的:
int *i_ptr = static_cast<int*>(*v_dptr);
int **i_dptr = &i_ptr;
static_cast
可以执行任何隐式转换的反向操作。
有一个隐式转换int*
→ void*
;它只不过丢失了关于指向对象的类型的信息。
没有隐式转换int**
→ void**
。如果允许,它将重新解释对象指针,即将int*
重新解释为void*
。在一些旧体系结构上,int*
不一定具有像void*
(或char*
,对齐要求最少的指针类型(那样具有那么大的值表示。
重新解释需要reinterpret_cast
。
恕我直言,通常使用reinterpret_cast
进行与void*
的转换是个好主意,因为这会向读者传达意图。然而,我记得萨特和亚历山德雷斯库建议使用static_cast
,大概是由于C++03缺乏正式保证。我还记得,这个纯粹的形式问题在第 11 C++ 中得到了解决。
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 运行时错误:引用绑定到类型为"int"的空指针
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 为什么我在空指针错误(链表)中获取成员访问权限
- 从向量到空指针的 memcpy(反之亦然)不起作用
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 成员访问是否在空指针上定义C++?
- 尝试将对象插入空指针数组时出现分段错误
- 为什么我们需要在 C++ 中检查空指针,而在 Java 中不需要?
- 是否允许向空指针添加零?
- 为什么 C 样式字符串的工作空指针检查不?
- 在函数内初始化无符号字符指针将返回空指针
- 为什么多维数组中的空字符串文本衰减为空指针?
- C++ 取消引用指向矢量的空指针时的分段错误
- 错误 C6011:取消引用空指针"NAME"。C++
- cppcheck取消引用空指针
- 打印空指针时,std::cout 可以打印 "NULL" 而不是 0 吗?
- 递增空指针无法正确设置值
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上
- 将多映射转换为空指针,然后转换回多映射