Keith said:
Ok, I can *sort of* see your point here. Without the cast, the
expression is of type void*, which will be implicitly converted to any
pointer-to-object type. It's less safe in the sense that if you apply
sizeof to the wrong thing, the compiler won't warn you about it:
(A):
double *p1;
int *p2;
p1 = malloc(sizeof *p2);
Whereas if you use the type, then getting the type wrong will give you
a constraint error and a required diagnostic:
(B):
double *p1;
int *p2;
p1 = (int*)malloc(sizeof(int)); /* Compiler catches error */
But if you have the correct type in the cast, but the wrong type in
the sizeof argument, you're back to another error that the compiler
won't catch:
(C):
double *p1;
int *p2;
p1 = (double*)malloc(sizeof(int));
What you're doing is basically case (B) with the two occurrences of
the type name kept in synch by using a macro.
Yes, given that (B) is *exactly* quoted
((Type*) malloc (sizeof (Type))).
And (C) is irrelevant (but it adds to that many potential errors I am
going to step onto, yes?)
But if you want to use a macro, why not apply the same technique to
case (A), giving you just as much safety?
(D):
#define NEW_OBJ(ptr) ((ptr) = malloc(sizeof *(ptr)))
#define NEW_ARR(ptr, count) ((ptr) = malloc(count * sizeof *(ptr)))
Perhaps I want to do
Foo **array;
*array++ = CALLOC_OBJ(Foo);
with CALLOC_OBJ doing calloc(sizeof(Foo), 1) in this case (it's g_new0()
in glib-using code). In any case I don't know why I would want to use
NEW_OBJ(ptr) which modifies ptr just to use The Right (or how people say
"idiomatic in c.l.c") 'sizeof *ptr'.
double *p1;
int *p2;
NEW_OBJ(p1);
if (p1 == NULL) {
/* allocation failed */
}
NEW_ARR(p2, 10);
if (p2 == NULL) {
/* allocation failed */
}
Personally, I'm content to keep the sizeof argument consistent
manually, but you can use macros to do this for you *without* using
unnecessary casts.
Of course I can. As well I can avoid using goto, I can have single
return in any function, or (going other direction) I can avoid using
stream methods from stdio.h and use raw open/close/read/write, or...
But why? I have never claimed it's necessary to use casts. I did claim
using casts is nice and most importantly harmless in some situations.
You may not agree with "nice" part but you have to prove yet cast
can harm there.
Keith, please tell, did I claim I can't do without casts? If no,
why do you invent extra macros to demonstrate how I can do that?
I could just use malloc(whatever_is_right_in_c_l_c). If yes,
please quote that.
People again and again tell why I don't have to use cast or something.
I am refusing to follow the advice and then they tell gods will
punish me, and to prove that they show all kinds of errors possible
elsewhere in other situations. Why?