[comp.sys.sun] Argument passing on SPARCs

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