Also, let's not forget that implicit casts between unrelated pointer types is only a warning in C. Fortunately, modern C compilers started treating it as an error by default because it caused so much harm: https://gcc.gnu.org/gcc-14/porting_to.html. In C++ this was always a compiler error.
A warning in C has the meaning of a "stern warning" aka. "That very much won't work, I warned you!". An error means, "I literally, don't what you mean".
Also as far as I know, the C standard only talks about diagnostics.
(Another pet peeve of mine is that missing returns in functions is not considered a hard error. GCC 16 does not even issue a warning by default when compiling C code, which is just crazy. "-Werror=return-type" is the first thing I do in every new C or C++ project. I don't understand how this is still not the default...)
That's because the default mode for compilers is to just shut up and compile this throw away code. Programmers know that you are expected to turn the warnings on and also nobody is manually invoking compilers directly. The default for build systems is often "-Wall -O2" anyway. Personally I prefer the status quo, I hate tools, that I just invoke and they start spamming my terminal. "Like, I know, that there will be issues, that's why I'm using you, but you don't need to tell me until I told you what exactly you are supposed to report me. Don't spam me until I ask you."
> Why lump serious issues like incompatible pointer casts together with benign things like uninitialized variables?
?? Uninitialized variables are also serious issues and also undefined behaviour. If anything they're more serious, because for pointer casts, it is likely that the types are compatible, but the compiler just doesn't know it, while truly uninitialized variables are always a real error. For the latter, the issue is rather, that the compiler often can't proof whether the variables are actually uninitialized. That's why it is more likely to meet a "maybe-uninitialized", a true "uninitialized" is rare in the wild.
That's just not true. Compilers do issue certain warnings by default and they even treat some warnings as errors. See https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
> ?? Uninitialized variables are also serious issues and also undefined behaviour.
Oh my, I meant to write "unused variables" facepalm. Uninitialized variables are of course a serious issue.
So back to my original point: you said that warnings in C are always a serious thing, but that's not really true. Warnings can range from more or less harmless to very serious. In fact, compilers recognize this issue by upgrading certain warnings to errors by default. See again my link to the GCC 14 post: https://gcc.gnu.org/gcc-14/porting_to.html.
I’m not arguing that that’s better, or worse, but it’s definitely true and by no means a myth.
I.e. most of the time the typing in real C++ code isn't meaningfully stronger than that found in C code.
...so much this! A void pointer is an "any-pointer" by design. It shouldn't require casting from and to specific pointer types, that defeats the whole point of having void pointers in the first place.
You don't need to explicitly cast T* to void* (guaranteed to be safe), you only need to cast when converting out of void*.
The rules are basically the same as casting between pointer-to-derived-class and pointer-to-base-class and they make sense.
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).
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.