[英]Void ** a generic pointer?
void *
是一个通用指针,但是void **
呢? void **
也是通用指针吗?
我们可以将void **
类型转换为int **
、 char **
等等。
我将感谢堆栈溢出家庭提供有关此的任何信息。
不。 void**
是指向void*
的指针,没有别的。 只有void*
就像一个通用指针。
请注意,实际尝试它可能会产生一致的结果,但只有以上内容是标准规定的,其他任何内容都是未定义的行为,可能会毫不留情地崩溃。
void**
是指向void*
的指针。 除了它是未定义的行为(虽然可怕,但行为通常实际上是由您的编译器定义的),如果您执行reinterpret_cast
,这也是一个大问题:
int x = 3;
char c = 2;
int* y = &x;
void* c_v = &c; // perfectly safe and well defined
void** z = reinterpret_cast<void**>(&y); // danger danger will robinson
*z = c_v; // note, no cast on this line
*y = 2; // undefined behavior, probably trashes the stack
指向指针的指针与指针是非常不同的野兽。 在指针上相对安全的类型更改在指向指针的指针上并不安全。
使 ** 通用指针无效?
void **
不是通用指针。 标准只说void *
是通用指针。
关于指向指针的指针和内存分配的一方面:尽管
malloc
返回的void *
类型是一个通用指针,适用于分配给任何类型的指针或从任何类型的指针分配,但假设类型void **
不是指向的通用指针指针。
我们可以将
void **
类型转换为int **
、char **
等等。
不,你不应该。
C-FAQ说:
C 中没有通用的指针到指针类型。
void *
仅用作通用指针,因为在将其他指针类型分配给void *
或从void *
分配其他指针类型时,会自动应用转换(如果需要); 如果尝试对指向void *
以外的指针类型的void **
值进行间接尝试,则无法执行这些转换。 当您使用void **
指针值时(例如,当您使用*
运算符访问void **
指向的void *
值时),编译器无法知道该void *
值是否曾经从其他一些指针类型转换而来。 它必须假设它只不过是一个void *
; 它不能执行任何隐式转换。换句话说,您使用的任何
void **
值必须是某处实际void *
值的地址; 像(void **)&dp
这样的强制转换,虽然它们可能会关闭编译器,但它们是不可移植的(甚至可能无法执行您想要的操作;另见问题 13.9)。 如果void **
指向的指针不是void *
,并且它的大小或表示形式与void *
,则编译器将无法正确访问它。
C 实现可以自由地扩展语言,允许void**
在合适的强制转换运算符存在的情况下用作指向任何类型的通用指针,并且在标准实现之前的日子里实际上可以做到经常这样做。 该标准并未强制要求进行此类处理,因为有些平台无法有效地适应此类使用。 据推测,作者认为,要求需要让他们的代码在此类平台上工作的程序员跳过箍以解决缺少“指向任何数据指针的指针”类型的问题,这比要求实现跳过箍以适应的危害要小此类结构不考虑其客户是否会使用它们。 这样的判断并不意味着标准的作者打算要求程序员跳过这样的圈套,即使在编写永远不会被要求在此类平台上运行的代码时也是如此。 Clang 和 gcc 可以配置为通过-fno-strict-aliasing
选项支持此类构造。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.