[m]allocation question

Doug Gwyn gwyn at smoke.BRL.MIL
Sun Sep 30 11:15:23 AEST 1990


In article <871 at usage.csd.unsw.oz.au> cameron at spectrum.cs.unsw.oz.au (Cameron Simpson) writes:
>From article <13946 at smoke.BRL.MIL>, by gwyn at smoke.BRL.MIL (Doug Gwyn):
>| In article <UaxqffS00Vtq8akksB at andrew.cmu.edu> ghoti+ at andrew.cmu.edu (Adam Stoller) writes:
>|>        t = (struct node *) malloc(sizeof *t);
>|>Isn't *t garbage at the time the sizeof is performed - isn't this
>|>[almost?] de-referencing a NULL pointer.
>| We went through this about a year ago in a different guise.
>| The outcome of that discussion was that, since the argument to sizeof
>| is NOT evaluated, there is no attempt to access through that pointer,
>| and only the type (not the value) of the hypothetical result is
>| relevant.  Thus sizeof(*t) is obliged to work even if t contains a
>| garbage value.
>This interests me. I seem to recall an extended discussion (maybe in
>comp.std.c) concerning ways to determine the size of a structure member.
>I have been using the macro
>    /* size of a field - may break under ANSI, but hasn't yet */
>    #define		fsizeof(type,field) sizeof(((type *)NULL)->field)
>for some time. I have recollections of remarks to the effect that the
>above locution could break under a conformant compiler. Could someone
>either correct me ("yes, Cameron, fsizeof() is ok") or re-iterate the
>explaination of why this macro can break, while sizeof(*t) is fine.

I probably overstated the validity of the construct "sizeof *t" when t
contains an invalid value.  Strictly speaking, 3.3.3.2 labels this a
case of "undefined behavior", and it doesn't state or imply that an
evaluation must be attempted for the result to be undefined.  However,
the normal implementation of sizeof() will not try to determine the
validity of the contents of t in such an expression, but will rather
rely solely on the type information, which is well-defined.  Thus, this
situation is one of those cases of "practically portable" rather than
"guaranteed portable" (among conforming implementations).  I personally
wouldn't use such a construction if it could be avoided.

The case of "sizeof ((type*)0)->field" is slightly more ambiguous --
the standard says in 3.3.2.3 Semantics that it "designates a member of
a structure or union object"; it also says what the value is, in terms
of thge pointed-to object, but that is not relevant in the context of
sizeof since there is no evaluation of the operand of sizeof.  A
reasonable argument can be given for either choice of interpretation;
I don't recall X3J11 having issued an interpretation ruling or a
response to public comment that specifically addresses this point.
It would be useful to obtain a definitive ruling on these examples.
Meanwhile, I recommend avoiding relying on such "grey areas" of the
language definition, because even if we all agree what the standard
says should happen, there is some chance that at least one actual
implementation will disagree, forcing you to change the code anyway.



More information about the Comp.std.c mailing list