Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!cornell!uw-beaver!rice!sun-spots-request From: stevec@lccr.cs.sfu.ca (Steve Cumming) Newsgroups: comp.sys.sun Subject: unions as function arguments Message-ID: <892@fornax.UUCP> Date: 4 Mar 89 07:02:47 GMT Sender: usenet@rice.edu Organization: Sun-Spots Lines: 97 Approved: Sun-Spots@rice.edu Original-Date: 21 Feb 89 21:45:31 GMT X-Sun-Spots-Digest: Volume 7, Issue 180, message 11 of 12 A lot of applications have constructions that look like this: typedef union { int a; char *b; struct c *d; float e; } foo; main(){ foo c; init(0,0); /* initialise the head of an attribute list */ . . . } init(a,b) int a; foo b; { if (a == 0 && b.a == 0){ /* init some tables and return*/ return; } return; } This produces unpleasant results on Sun4's under SunOS4 and SunOS4.01. Usually segmentation faults in the case of calls like the call to init, above. The symptoms vary with the exact contents of the union. But compiling with -misalign does not make them go away in all cases. Programmes like pic and Unipress emacs are riddled with calls of this sort. What I want to know is, is it legal to pass a union to a function? Reasonably careful examination of K&R (both editions) makes me think that it is. Am I right? The fact tha Famous (tm) People wrote some of the code in question also makes me thinks so. In that case passing a constant 0 as a union should cause the compiler to do the obvious thing. It don't. Can anyone state authoritatively whether such constructions should work or not? Here is another, slightly different, example, which reliably causes a Sun 4 to crash: main() char *a = "a"; /* call _DefMac,1 with %o0 pointing at "a" */ DefMac(a); exit; } DefMac(body) union { char * b_name; char * b_string; } body; { char * foo = body.b_string; /* ld [%i0],%o0 st [%o0],[%fp+-0x4] ld [%fp+-0x4],%o1 */ a = *foo; /*dies here on: ldsb [%o1],%01 */ return; } The attempt to dereference foo seems to tickle the infamous Sun4 watchdog reset bug. Again, compiling with -misalign does not fix the problem, although it yields more verbose code. I do not have access to enough data on SPARC to make sense out of the .s code - the effect is that of an extra level of dereferencing, but it all looks OK to me. Sun has fixed this is 4.01. Steve Cumming stevec@lccr.cs.sfu.ca {uunet|...}!ubc-cs!fornax!stevec School of CS SFU (604) 291-4399 ... I'll be far off and gone Vancouver, CDN like summer wages. [[ But it's not all okay. In the second example, "main" passes a "char *" to a function that expects a union. This is clearly wrong. In the first case, I believe that "0" is not sufficient. To be safe, one should set one member of a dummy union to 0 and pass that in. In general, I believe that passing and returning unions is legal (just liek it is with structures) , but calling a function with something it isn't expecting is never legal. --wnl ]]