panos@ncar.ucar.edu (Panos Tsirigotis) (11/21/90)
In article <1990Nov4.031554.3208@rice.edu> brad@ds3.bradley.edu (Bradley E. Smith) writes: >I always thought that unions were passed by value. Anyways I need this >program to work, or I will have to rewrite a bunch of things. The problem has to do with the way the compiler passes arguments to a function. The first 8 arguments are passed in registers (assuming they are chars, shorts, ints, longs, floats, doubles or pointers). Everything else is passed on the stack and their address is passed in a pointer. The problem does not exist on the other CPUs you mention because the compilers for them pass arguments on the stack only. |Is it me or is the compiler bugging (FYI: 4.0.3 and 4.1 have the same |problem, and gcc does the same thing). | |union u { | int i; | long l; | char c; | float f; | char *cp; |}; | | |main() |{ | union u x,z; | | x.i = 100; | z.i = 99; | printf("sizeof(u) = %d\n", sizeof(x)); | printf("sizeof(int) = %d\n", sizeof(int)); | (void) doit(x,z); Here the compiler places x and z on the stack. Registers %o0 and %o1 contain the addresses of x and z respectively. > (void) doit(0,0); Here the compiler loads %o0 and %o1 with 0. > exit(0); >} >doit(a,b) Your function expects its arguments on the stack (because they are unions) and their addresses in %i0 and %i1. In the case of the second doit call %i0 and %i1 contain 0 and when the function tries to derefence them (to get the values of a.i and b.i) it gets a segmentation fault. >union u a; >union u b; >{ > (void) printf("%d, %d\n", a.i, b.i); >} For more info, check a document that is called PORTING SOFTWARE TO SPARC SYSTEMS (it is part of the Sun manuals). It is not very explicit on this particular problem but it contains a lot of other useful pieces of information. Panos