One obvious point here is of course that if you don't know malloc() then you don't know C. Considering C is a pretty small language, and that malloc() isn't exactly at the furthest, most dusty and least-trodden part of its standard library, I think this is basic knowledge for anyone writing C.
That said, I'm not sure I agree since implicit pointer conversions are not in general allowed, except to/from void * and then there will always be a properly typed thing close by (like the left-hand side in this example).
Can you provide an example of where an implicit pointer conversion creates danger?
> Can you provide an example of where an implicit pointer conversion creates danger?
In your malloc example, there's no real danger because you used sizeof. But when it is written with a type like this:
bar = malloc(sizeof(BarType));
Then there's danger if the type of bar does not match BarType *, perhaps after changes.
Writing it like this:
bar = (BarType *)malloc(sizeof(BarType))
ensures the type mismatch will cause a compile-time error instead of UB.
That's not a strong argument, obviously, as you can use sizeof(*bar) instead. But it is an example of a situation where an implicit pointer conversion creates danger.
(I would also argue that a malloc(sizeof(type)) is more idiomatic and familiar C, so using it with other people will raise fewer eyebrows even if it's not strictly the safer choice.)
So when would it occur without sizeof(*bar) being an option? When there's a type-erased container:
foo = list_get(FooType, foo_list, index);
bar = hash_get(BarType, bar_hash_table, key);
If those are generic containers whose accessors return void *, you will be in trouble with UB here if the type of *foo or *bar don't match FooType and BarType respectively, perhaps after changes.
When you add the cast, again the type mismatch will cause a compile-time error.
In this case, there's no need to write the cast at the call site. Since list_get and hash_get must be macros, it's better to put the cast inside those macros. But the cast should exist, to catch the type mismatch, rather than those returning void * and relying on implicit cast rules.
(If you want to get fancy, there's a way to avoid having to pass the container item-type to those macros as an argument, but I've never seen it used in practice.)
One obvious point here is of course that if you don't know malloc() then you don't know C. Considering C is a pretty small language, and that malloc() isn't exactly at the furthest, most dusty and least-trodden part of its standard library, I think this is basic knowledge for anyone writing C.
That said, I'm not sure I agree since implicit pointer conversions are not in general allowed, except to/from void * and then there will always be a properly typed thing close by (like the left-hand side in this example).
Can you provide an example of where an implicit pointer conversion creates danger?