I do not think C++ is more expressive or type safe.
I do not think C++ is more expressive or type safe.
$ echo -ne "#include <stdlib.h>\nint foo() { return malloc(42); }" | gcc -xc -fsyntax-only -c -
<stdin>: In function ‘foo’:
<stdin>:2:20: warning: returning ‘void *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
Whereas in C++ it's a hard error: $ echo -ne "#include <stdlib.h>\nint foo() { return malloc(42); }" | gcc -xc++ -fsyntax-only -c -
<stdin>: In function ‘int foo()’:
<stdin>:2:26: error: invalid conversion from ‘void*’ to ‘int’ [-fpermissive]
Does this not count as "more type safe" to you?I do want an error when I violate types, I do not want it for void, because that's the whole meaning of void. C++ manages to make it the worst of both worlds.
I’m mostly happy with implicit casts from void* to int* or something. But in this code example, we see an implicit cast from void* to int, casting the pointer itself into a number that might not even fit the pointer. This is rarely what you want. I’d much rather explicit casts in this case.
My understanding is that C has a different understanding of the word warning than other languages. Such as in "stern warning" or "warning: the building will collapse if you take that brick out".
This is a philosophical problem. C has false positives to the question: "Is that a program", and some people find that to be idiotic (I don't, this is why I like C). But this becomes really logical, when you have in mind, that the point is that you do not want to have false negatives.
> Otherwise, if a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
The C++ standard does seem to explicitly require the compiler to reject translation units with a failed static_assert. (The requirements for #error are a little confusing; not sure if a failed #error in a conditional block requires failure.) But I couldn't find a rule that mandates failure for invalid implicit int conversions. Implicit pointer to int conversions are invalid for the same reasons in both C and C++. Basically, AFAICT C++'s type safety in this regard is a matter of historical compiler behavior, and now the major C compilers are adopting that behavior, which they previously had allowed (with a mandatory diagnostic message) for backward compatibility reasons.