Out of interest, which compilers do warn about correct usage of
malloc?
You mean assigning void* to a pointer to non-void? At least one I've
used (could have been the IAR H8 series compiler, but I wouldn't
guarantee it).
The worst I've seen is a warning when you cast something to
the same type it already was. For example:
isprint( (unsigned char)ch );
If you compile with plain char unsigned, it will warn about this
cast.
Try things like:
unsigned char ch;
int in;
in = getc(stdin);
if (in != EOF)
ch = in;
On some of the ARM compilers it gives a warning:
conversion from 'int ' to 'unsigned char ', possible loss of data
It gets really annoying in macros, where you often put in casts
because the macro could really be called with any integral type,
and then this compiler would warn when you use the one type that
matches the cast.
It was possible to turn off this warning, but not without also
turning off important warnings. :X
Exactly. And the 'silly' warnings can mask the real ones (and even mask
the rrors, I've had occasions where it's taken me a lot of time even to
find the error message knowing that there is one, because it's been lost
in the 'noise' of the spurious warnings).
How many platforms have you programmed on where int, size_t,
and void* are not interchangeable, and the compiler does not
have special recognition of standard library functions?
Lots. Including (but not limited to, these are only the ones which I
remember definitely had different sizes for at least one of those
types):
Z8000
M68000
H8 family
80x86
The only "special recognition" by the compilers has been when the
appropriate header -- and therefore the appropriate prototype -- has
been included.
I haven't programmed for a C compiler where int and void* were
interchangeable without a cast since I left university where we had a
pre-K&R compiler (thinking of it, I don't think it had void at all so
they weren't interchangeable then either).
There would not have been any diagnostic in either case, if the
parameter to malloc were wrong, ie.
pointer = (correct_type*) malloc(sizeof(my_type));
True. Easier is to do something like:
#define NEW(t) ((T*)malloc(sizeof(T)))
and then
int *p = NEW(char);
gives a diagnostic (usually an error, occasionally a warning).
So this is a bit of a Pascal's wager.
Note that this problem can be eschewed with:
malloc(sizeof *ptr);
But that doesn't catch the case where you know what the type should be
and you want to ensure that the pointer is the correct type.
Chris C