Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!aussie!rex From: rex@aussie.UUCP (Rex Jaeschke) Newsgroups: comp.std.c Subject: Re: A question about sizeof Message-ID: <46.UUL1.3#5077@aussie.UUCP> Date: 23 Oct 90 16:09:17 GMT References: Organization: Journal of C Language Translation Lines: 67 > (Erkki Ruohtula) writes: > The standard says that "sizeof something_of_array_type" gives the size of the > array, not that of the pointer to the first element. But when does the > "arrayness" disappear in the conversion to pointer? What should > "sizeof (struct_pointer->field_of_array_type)" be? Do the parentheses affect > the interpretation? In C, an expression that designates an array is converted to a pointer to the first element except when it isn't. Very clear, right? Well, there are only 3 situations where the conversion DOES NOT take place. They are, when the array designating expression is the operand of sizeof or & (remember that ANSI C allows you to take the address of an lvalue array expression), and in a special case of initialization. An example of the latter case, char *pc = "abcd"; the expression "abcd" designates an array of 5 chars and this expression IS converted to a char *. However, in the case of char c[] = "abcd"; the `expression' "abcd" is treated as short-hand notation for {'a', 'b', 'c', 'd', '\0'} and there is NO conversion. In the case of sizeof (struct_pointer->field_of_array_type) the operand still has array type so there's no conversion. The parens are redundant and have no effect. Now something not well understood is that conversions of arrays to pointers is ONLY defined for array expressions that ARE lvalues. The semantics when they are not lvalues is undefined. For example, given struct tag { char c[5]; }; struct tag f(void); what happens with f().c? f returns a struct by value and c is an array member of that structure. However, f() is NOT an lvalue which means that f().c is NOT an lvalue and so it is undefined as to what happens. Certainly you cannot rely on the array/pointer conversion. This is the only place I've been able to come up with an array expression having these properties. (g()->c is not a problem since g()->c can be an lvalue even if g() is not.) In a related situation, given void f(void), what is sizeof(f)? I've had several compilers convert the function designating expression f to a pointer to function and therefore producing an answer. ANSI C, however, says (and K&R implies) this is incorrect and that there is no conversion done making the construct invalid. Why? Because sizeof can only be applied to objects having completed type and a function is not an object. Also, sizeof(f) is equivalent to sizeof(void (void)) and the latter clearly is erroneous. Rex ---------------------------------------------------------------------------- Rex Jaeschke | Journal of C Language Translation | C Users Journal (703) 860-0091 | 2051 Swans Neck Way | DEC PROFESSIONAL uunet!aussie!rex | Reston, Virginia 22091, USA | Programmers Journal ---------------------------------------------------------------------------- Convener of the Numerical C Extensions Group (NCEG) ----------------------------------------------------------------------------