Xref: utzoo comp.lang.c:13659 comp.std.c:466 Path: utzoo!yunexus!geac!syntron!jtsv16!uunet!lll-winken!lll-tis!ames!mailrus!ncar!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c,comp.std.c Subject: Re: union *func() Keywords: union, pointers, functions Message-ID: <14201@mimsy.UUCP> Date: 28 Oct 88 07:56:13 GMT Article-I.D.: mimsy.14201 References: <2205@arcturus> <14172@mimsy.UUCP> <1585@solo8.cs.vu.nl> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 84 ... and union func(): >In article <14172@mimsy.UUCP> I noted that >> a = function().member; >> >>is conforming, etc., if function() returns a structure or union and the >>`member' field corresponds, etc., with one additional restriction: >>the member must not be an array. In article <1585@solo8.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) asks why the restriction exists. `function().member' above is used in an rvalue context; as such, if the member is an array, this amounts to taking the address of part of a structure or union valued function. If, as is common in some compilers, the return value is in fact copied into local temporary storage, it may not have an address. In particular, consider the following: struct arr { int arr[10]; }; struct arr fn(); main() { int *p; p = &fn().arr[8]; printf("fn 3,4 = %d,%d; p = %p\n", p[0], p[1], (void *)p); } This might `want' to compile into something like this: main_: | { mov fp,-(sp) | make stack frame mov sp,fp | int *p; sub #2,sp | make stack space for local `p' | fn() sub #20,sp | make room lea (sp),r0 | address of return space call fn_ | fn() lea (sp),r0 | compute address of return value | & .arr[8] lea 16(r0),r0 | p = mov r0,-2(fp) | store in p | ; add #20,sp | done with return value | p mov -2(fp),r0 | noop, hope optimiser pulls it out mov r0,-(sp) | push p | p[1] mov -2(fp),r0 | noop, hope optimiser pulls it out mov 2(r0),-(sp) | push p[1] | p[0] mov (r0),-(sp) | push p[0] | "string" pea S1 | push address of string | printf(...) call printf_ | printf the various variables add #8,sp | fix stack | } mov fp,sp | undo frame mov (sp)+,fp ret There is a problem here: pushing p clobbered p[1]! Anyway, it is legislated out, as is such stuff as struct arr fn(); main() { fn().arr[2] = 3; } (At least, I *hope* stuff like the latter is illegal, given that the point of the original restriction above is to allow structure return values to be done using invisible temporaries....) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris