Article View: comp.std.c
Article #1761Re: [m]allocation question
From: Doug Gwyn
Date: Sun, 30 Sep 1990 01:15
Date: Sun, 30 Sep 1990 01:15
46 lines
3354 bytes
3354 bytes
In article <871@usage.csd.unsw.oz.au> cameron@spectrum.cs.unsw.oz.au (Cameron Simpson) writes:
>From article <13946@smoke.BRL.MIL>, by gwyn@smoke.BRL.MIL (Doug Gwyn):
>| In article <UaxqffS00Vtq8akksB@andrew.cmu.edu> ghoti+@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.
Technical Details
Message-ID:
<13966@smoke.BRL.MIL>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!aplcen!haven!adm!smoke!gwynReferences:
<13946@smoke.BRL.MIL> <871@usage.csd.unsw.oz.au>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!aplcen!haven!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn) Newsgroups: comp.std.c Subject: Re: [m]allocation question Message-ID: <13966@smoke.BRL.MIL> Date: 30 Sep 90 01:15:23 GMT References: <13946@smoke.BRL.MIL> <871@usage.csd.unsw.oz.au> Organization: U.S. Army Ballistic Research Laboratory, APG, MD. Lines: 46