为什么我的 static_cast 指针失败了?

Why is my static_cast of a pointer failing?

为什么我的 static_cast 指针失败了?

int iDog = 456;
int *piDog = &iDog;
long *plDog = static_cast<long*>(piDog); // invalid type conversion

long lDog = static_cast<long>(iDog);    // ok

long* plDog = (long*)(piDog); // this is OK too... very weird!! (Dynamic cast... and we aren't allowed to use this one in our coding standards)

这个参考表明应该没问题:https://en.cppreference.com/w/cpp/language/static_cast

Visual Studio C++ 有问题?

TL;DR: 如果你的转换成功,该语言将不会为指针提供类型安全保证,并且是引入 C++ 样式转换的动机的关键部分而不是坚持使用老派的 C 演员表。

在 C/C++ 标准的语言中,long*int* 不是“指针兼容的”。您不能将 long* 隐式转换为 int*,反之亦然,因此 static_cast 不能在一次转换中完成。

The reasoning behind that is sizeof(long) is not always equal to sizeof(int) for all platforms. They are distinct fundamental types. This is true in general of all distinct C/C++ types even if they have an identical binary layout. They are only "pointer-compatible" if in the syntax of the language you declare the types to be related via implicit conversion.

void* 转换为指向对象类型的任何指针时,您可以使用 static_cast,反之亦然。

因此您可以通过两种方式做到这一点:

  • reinterpret_cast<long*>(piDog);

-或-

  • static_cast<long*>(static_cast<void*>(piDog));

在文体上,reinterpret_cast 的使用更加清晰。在任何一种情况下,转换的有效性都取决于体系结构,并假定 sizeof(int) == sizeof(long) 以及具有相同的内存布局。

IOW This is safe for Windows x86 and x64 native, but may not hold for other platforms or CPUs. This is one of the reasons Windows x64 choose to use the LLP64 data model as explained in this blog post.

请参阅 static_cast and reinterpret_cast

的 cppreference
long *plDog = static_cast<long*>(piDog); // invalid type conversion

Why is my static_cast of a pointer failing?

因为格式错误。 static_cast 的 None 规则适用于您正在尝试的转换。正如您在评论中提到的,这是一个无效的转换。

指向一种对象类型的指针不能静态转换为指向另一种对象类型的指针,除非它们是指向相关 类 的指针,或者在将 to/from 指针转换为 void 时。

This reference suggests it should be OK: https://en.cppreference.com/w/cpp/language/static_cast

该参考表明您尝试的转换不正确

long* plDog = (long*)(piDog); // this is OK too... very weird!!

这是一个格式正确的转换。一点都不“奇怪”。

有许多转换是显式转换(也称为“强制转换符号”或“C 风格转换”)允许的,而静态转换是不允许的。这是因为静态转换具有(至少是表面上的)类型安全性,而显式转换本质上要求编译器假装类型系统不存在。

请注意,通过 plDog 间接访问对象会导致未定义的行为。如您所见,收到错误是件好事。

and we aren't allowed to use this one in our coding standards

这是一个很好的限制。这将使您的团队更难通过错误地绕过类型系统来编写错误。

Issue with Visual Studio C++?

不,问题是程序格式错误。编译器正确告知您该错误,并且不需要编译该程序。


我建议问问自己:你为什么想要,或者认为你需要做这样的演员表?