Comment by ranger_danger

5 hours ago

In C, assigning the return value from malloc() to a specific type merely produces a warning:

  $ 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?

What version is your compiler? As of GCC 14 and clang 15 an implicit pointer conversion to int is an error, not merely a warning; and this is without specifying any special conformance or warning modes. I think implicit int conversions have been a constraint violation since at least C99, requiring a diagnostic, though I'm not sure if the switch to an error instead of a warning was prompted by a change in wording in C23 or just a general change in attitude and less concern with failing on pre-existing (but wrong) code.

  • This was GCC 11. I did try clang 15 and got an error (whereas 14 did not), but my point was that the language spec itself allows this, regardless of any specific compiler, and the original argument (as I understood it) was about the type safety of C and C++ (the language specs) themselves.

No, this counts as C++ is stupid to me. The memory returned by malloc is UNTYPED. The sole reason why void as a type exists is to convey the notion of no type, so that it needs to be assigned to a type by a programmer. If you mean "byte region, please cast before use" that's 'char *'. Since C++ now forces me to write a cast, it effectively forces me to hide and silence errors.

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.

  • Nah. Malloc’s return type is a pointer. The memory pointed to by a malloc call is untyped. But the return type isn’t void. It’s void*, aka a pointer to unknown.

    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.