Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!cs.utexas.edu!uunet!crdgw1!crdos1!davidsen From: davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) Newsgroups: comp.lang.c Subject: Re: sizeof a struc field Summary: That isn't what's happening Message-ID: <1234@crdos1.crd.ge.COM> Date: 18 Oct 89 19:21:57 GMT References: <7710@microsoft.UUCP> <11086@smoke.BRL.MIL> <131@dtoa3.dt.navy.mil> <11316@smoke.BRL.MIL> Reply-To: davidsen@crdos1.UUCP (bill davidsen) Organization: GE Corp R&D Center Lines: 81 In article <11316@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes: | I said that dereferencing a null pointer CONSTANT was meaningless, | and it is EXACTLY the kind of thing I want compilers to check for | me at compile time. But the pointer is not being dereferenced. A pointer can't be dereferenced at compile time. Examples which work with pcc and gcc and appear valid as I read the standard: (1) int *foo = (int *)0; int bar = sizeof(*foo); (2) void test(x) struct mytype *x; { int m = sizeof(x->a); /* x certainly could be NULL */ } Now the pointer foo is not being dereferenced, sizeof a pointer with an indirect is evaluated by taking the size of the type of the object to which the pointer *may* validly point. This is done at compile time, asis example (2), where the type of field a within struct mytype is used to set the initializer. What the original poster wanted was the size of a field within a struct. He proposed using: sizeof(((struct mytype *)0)->field) which involves using a null values pointer. The value of this under pcc compilers is the size of the field within a struct mytype. You interpret the standard to forbid this. Do you also interpret the standard to forbid: struct mytype { int a, b; } *head = (struct mytype)0; int fieldlen = sizeof(head->a); I would first note that sizeof always works on the *type* of the object. Not only things like "sizeof(int)" but "sizeof(xyz)" must be done by type, since xyz is not an allocated object at compile time, what is really delivered by the sizeof operator is the size of the generic type of xyz. I realize that there are good reasons for not dereferencing NULL pointers, but since the sizeof operator actually returns the size of the *type* of the specified object, I certainly can't see any technical reason why the original construct should be rejected, since the type information is available at compile time, and the value of the pointer is not. The compiler can't validate the value of the pointer in any other case, why should it be required or even allowed to do so in this case. Here's what the standard says (3.3.3.4): The *sizeof* operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an lvalue that designates a bitfield object. The *sizeof* operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined by the type of the operand, which is not itself evaluated. The result is an integer constant. ================ end quote ================ If the expression is not evaluated the pointer is not dereferenced and there is no problem as far as hypothetical hardware which checks for this. I see nothing which I can read to forbid the original construct or indicate that it might not be valid in this case. The meaning of an incomplete type is spelled out in 3.1.2.5 and a null pointer with a cast isn't shown. I therefore conclude that the construct of the original poster is valid C as specified by the standard. I also really wonder why sizeof doesn't return "unsigned int" but I suspect i wouldn't like the answer. -- bill davidsen (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) "The world is filled with fools. They blindly follow their so-called 'reason' in the face of the church and common sense. Any fool can see that the world is flat!" - anon