Path: 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 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 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.