On Thu, 2004-09-16 at 12:19, Tom Lane wrote:
> I prefer
>
> ptr = (foo *) malloc(sizeof(foo));
> or
> ptr = (foo *) malloc(n * sizeof(foo));
> since here you will get a warning if ptr is typed as something other
> than foo *.
I was leaving out the cast above because IMHO that's somewhat
orthogonal. If you like the cast (personally I'm in two minds about it),
then I'd argue for:
ptr = (foo *) malloc(sizeof(*ptr));
IMHO this is preferable because there is nothing that you need to change
when the type of "foo" changes that the compiler won't warn you about.
In your formulation you need to manually keep the two instances of "foo"
in sync: admittedly, not a huge deal because you need to change the
"foo" in the cast anyway, but IMHO it's worth enough to prefer the
sizeof(lvalue) style.
> No doubt you'll say that "ptr" is duplicated close together in your
> preferred version, but I don't think it scales nicely to
> slightly-more-complex cases. Consider for instance
>
> ptrs[i++] = malloc(sizeof(*ptrs[i++]));
>
> This is going to confuse people no matter what.
I try to avoid writing "clever" code like that in any case -- using
sizeof(type) would definitely make the above clearer, but IMHO that kind
of complex lvalue is best avoided in the first place.
> I guess at bottom it's the funny semantics of sizeof-applied-to-an-
> lvalue-expression that I don't like. I think sizeof(type decl) is much
> more obviously a compile-time constant.
Granted, sizeof(lvalue) is a little unusual, but personally I think it's
just one of those C features that might be weird coming from other
languages, but is idiomatic C.
Anyway, I'm not religious about this -- since other people seem to
prefer the former style I'll revert the change.
-Neil