为什么允许static * of void *到另一种类型?

时间:2013-07-09 21:57:18

标签: c++ pointers casting void-pointers static-cast

我刚读这个帖子: 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 一个void *到任何东西。 (当然,将转换为来自任何其他指针的void *总是可以的。)

那么为什么这些可能性中没有一个是真的 - #2和#3既可以允许也可以不允许?为什么它会像我的例子中所示那样工作?

3 个答案:

答案 0 :(得分:4)

cs = static_cast<char*>( static_cast<void*>(ucs) ); // 3) now it's allowed!

它会编译。这是否意味着允许?不。该标准仅允许从void*T*的转化,只有在void*转换获得T*的情况下,这不是您的情况。

答案 1 :(得分:1)

问题在于:

my_type *p = new my_type;
void *vp = p; // okay

现在,如果您需要返回原始指针,请执行以下操作:

my_type *new_p = static_cast<my_type*>(vp); // okay

没关系,结果很明确。如果使用static_cast将指针转换为不同的类型而不是原始指针,则会得到未定义的行为,而这通常不会被编译器检测到。所以演员是允许的,如果你误用它,它就在你的头上。

答案 2 :(得分:1)

好的,我会在这里回答我自己的问题,因为我觉得我有了一个想法,虽然我不确定它是对的。如果你认为我通过上/下投票得到它我可以告诉我,我想。 :)

所以我认为static_cast告诉编译器,“相信我,这是安全的。”而reinterpret_cast告诉编译器,“我知道这是不安全的;无论如何都要这样做。”

回到我的例子:

cs = reinterpret_cast<char*>(ucs);

是不安全的,但编译器仍会这样做,因为你告诉它。

cs = static_cast<char*>(ucs);

会导致编译错误,因为你说,“相信我,这是安全的”,但编译器知道它确实不是。所以它不信任你,因为它在这种情况下实际上知道,因此也就是错误。

现在最后一个例子有两个部分:

void* temp = static_cast<void*>(ucs);

当然是允许的,因为将转换为 void *是安全的。

cs = static_case<char*>(temp); // remember temp is a void*

是允许的,因为转换有时是安全的,有时候不是 - 编译器无法分辨它在任何给定的实例中...所以当你说“相信我,这是安全,“编译器信任你 - 如果你错了,那就在你的头上。 O.O

换句话说,你不能static_cast一些从不安全的事情 - 那时你需要reinterpret_cast ......但你可以 static_cast有时安全且有时不安全的东西(并且编译器无法分辨任何给定实例中的情况)。

所有这一切......我指的是“安全”和“不安全”在这里投下很多,但这些话究竟是什么意思呢? (所以,在某种程度上,我仍然不理解我自己的答案......!如果你可以帮我解决这个问题,请发表评论......)