【发布时间】:2013-07-07 16:40:36
【问题描述】:
我刚刚读到这个帖子: Simple c++ pointer casting
这让我开始思考为什么不允许不同指针类型之间的 static_cast(除非在这种情况下)除非您将 static_cast 转换为 void* 作为中间步骤。在我看来,两者都应该被允许,或者都不应该被允许。这是一个例子:
char* cs;
unsigned char* ucs;
cs = reinterpret_cast<char*>(ucs); // 1) allowed, of course
cs = static_cast<char*>(ucs); // 2) not allowed: incompatible pointer types
cs = static_cast<char*>( static_cast<void*>(ucs) ); // 3) now it's allowed!
在我看来,如果 #3 是可能的,那么 #2 也应该被允许。或者相反,如果由于指针不兼容(需要 reinterpret_cast)而不允许使用 #2,那么基于指针不兼容的原因,可能不允许 static_casting from void* 到任何东西。 (当然,将任何其他指针 转换为 void* 总是可以的。)
那么为什么其中一种可能性不是真的——#2 和#3 要么都被允许,要么都不被允许?为什么它会像我的示例中所示那样工作?
【问题讨论】:
-
因为 C++ 可以防止意外,而不是防止滥用。并且 C++ 重视安全性。
-
当然,您可以执行
const int i = 0; *const_cast<int *>(&i) = 1;并且它会编译,但它违反了约束并导致 UB。这就是void *的精彩之处。 C++ 显然没有设法完全消除 C 的类型不安全性。 -
@H2CO3 当然,但这就是 const_cast 所针对的那种不安全。同样,
unsigned char*到char*(显然)是那种不安全的 reinterpret_cast 是为了(不是 static_cast)......所以我想我的意思是,如果这对于 static_cast 来说“太不安全”,那么为什么不投射void*也需要 reinterpret_cast 吗? -
@DaveLillethun 因为
void *旨在与任何(数据)指针类型兼容。 -
@DaveLillethun:有一个特定的用例有效:从
T*转换为void*并返回T*,除此之外还有其他要与之交互的事情遗留的 C 风格 API。现在,一旦编译器得到void*,它就不可能知道它是来自char*还是unsigned char*,因此不需要诊断问题。
标签: c++ pointers casting void-pointers static-cast