Yes, downcasting can be unsafe and should be used carefully, but what's the alternative? At least in C++ you can't cast between unrelated types without an explicit reinterpret_cast (or C-style cast).
and you CAN use static_cast to convert from void*; this silently keeps working if you refactor the void* into a matching-type pointer later, while raising a compilation error if you refactor to a different-type pointer.
Yes, a static_cast would be safe, but then most C++ seems to use a C-style cast because it is less clunky and then is less safe than the corresponding C code. The issue is not that the downcast is unsafe (it is, but once you have a void pointer you already accepted this), but that it becomes even less safe by adding a C-style cast.
It is also not clear what is gained by forcing programmers to add a cast. Void pointers should be used sparingly anyway.
If C++ programmers do not use modern safety features, that's really their fault. C-style pointer casts should be flagged in code review.
> but that it becomes even less safe by adding a C-style cast.
At least in C++ there is a safer option. If you really want to be on the safe side, you can even to a dynamic_cast (assuming your code base allows RTTI).
> It is also not clear what is gained by forcing programmers to add a cast.
I think the point is to make it explicit and stand out.
I see your point. It would be nice if a C-style cast behaved like a static_cast in C++, but that's not possible because of backwards compatibility. At least with GCC/Clang you can disable C-style casts altogether with '-Werror=old-style-cast'. (Maybe there is a similar option for MSVC.)
Yes, this is something that would need a new language edition to properly fix. Compiler vendors could split -Wold-style-cast into separate warnings for static_cast and other usage though so that you can only ban one of them.
The point is that, there is nothing else to be done with a void pointer, other then downcasting it, and it needs to be downcasted to be used. There is no other check that somehow validates the cast, so there is no upside to requiring the cast, while it does potentially silence accidental casts once the type changed.
Yes, downcasting can be unsafe and should be used carefully, but what's the alternative? At least in C++ you can't cast between unrelated types without an explicit reinterpret_cast (or C-style cast).