我最近写了一些代码,发现自己做了很多c风格的演员表,如下所示:
Client* client = (Client*)GetWindowLong(hWnd, GWL_USERDATA);
我心想;为什么我们真的需要做这些?
我可以理解为什么在有很多代码的情况下需要这样做,编译器可能不会将哪些类型转换为什么类型,例如使用反射时。
但是当从一个long转换为两个类型大小相同的指针时,我不明白为什么编译器不允许我们这样做?
答案 0 :(得分:6)
当从一个long转换为两个类型大小相同的指针时,我不明白为什么编译器不允许我们这样做?
具有讽刺意味的是,这是编译器干预最重要的地方!
在绝大多数情况下,在long
和指针之间进行转换是一个编程错误,即使您的平台允许,也不会被忽视。
例如,当你写这个
时unsigned long *ptr = getLongPtr();
unsigned long val = ptr; // Probably an error
几乎可以肯定你在ptr
前面缺少一个星号:
unsigned long val = *ptr; // This is what it should be
在没有编译器帮助的情况下查找这样的错误非常困难,因此编译器希望您告诉它您知道何时进行类似的转换。
此外,在一个平台上运行良好的东西可能无法在其他平台上运行。例如,整数类型和指针在32位平台上可能具有相同的大小,但在64位平台上具有不同的大小。如果您想保持任何程度的可移植性,编译器应该警告您转换,即使在大小相同的32位平台上也是如此。编译器警告将帮助您识别错误,并切换到便携式指针整数类型intptr_t
。
答案 1 :(得分:4)
我认为我们的想法是,我们希望编译器告诉我们什么时候我们正在做一些狡猾和/或可能无意的事情。这样我们就不会意外地做到这一点。所以编译器会抱怨,除非我们明确地告诉编译器这是我们真正想要的。我们通过使用演员来做到这一点。
已编辑添加:
最好问一下为什么我们允许在类型之间进行转换。最初C
是作为强类型语言创建的。虽然它允许在相关对象类型之间进行升级/转换(例如在int和浮点数之间),但它应该阻止访问和分配错误类型作为语言特征,一种安全措施。然而,偶尔这是有用的,因此在我们需要的时候,使用语言进行转换以允许我们规避类型规则。