Next | Prev | Up | Top | Contents | Index

Varargs Routines

Attempting to recompile main.c foo.c -n32 results in two sets of warnings shown below:

%cc -n32 -O -o app1 main.c foo.c gp2.s

foo.c

!!! Warning (user routine 'foo'):

!!! Prototype required when passing floating point parameter to varargs routine: printf

!!! Use '#include <stdio.h>' (see ANSI X3.159-1989, Section 3.3.2.2)

ld32: WARNING 110: floating-point parameters exist in the call for "foo", a VARARG function, in object "main.o" without a prototype -- would result in invalid result. Definition can be found in object "foo.o"

ld32: WARNING 110: floating-point parameters exist in the call for "printf", a VARARG function, in object "foo.o" without a prototype -- would result in invalid result. Definition can be found in object "/usr/lib32/mips4/libc.so" The first warning points out that printf() is a varargs routine that is being called with floating point arguments. Under these circumstances, a prototype must exist for printf(). This is accomplished by adding the following line to the top of foo.c:

#include <stdio.h>

The second warning points out that foo() is also a varargs routine with floating point arguments and must also be prototyped. This is fixed by changing the declaration of foo() in main.c to:

foo(int, ...)

For completeness, <stdio.h> is also included in main.c to provide a prototype for printf() should it ever use floating point arguments.

As a result of these small changes, the C files are fixed and ready to be compiled -n32. The new versions are shown below.

/* main.c */
#include <stdio.h>
extern void foo(int, ...);

main()
{
   unsigned gp,ra,sp, get_regs();
   double d1 = 1.0;
   double d2 = 2.0;
   double res;

   gp = get_gp();
   printf("gp is 0x%x\n", gp);

   foo(7, 3.14, &gp, &ra, 
       &sp, d1, &d2, &res);

}


/* foo.c */
#include <stdio.h>
#include <stdarg.h>

void foo(int narg, ...)
{

  va_list ap;
  double d1;
  double daddr1, *daddr2, *resaddr; 
  unsigned *gp, *ra, *sp;

  va_start(ap, narg);
  printf("Number of Arguments is: %d\n",narg);

  d1 = va_arg(ap, double);
  printf("%e\n",d1);

  gp = va_arg(ap, unsigned*);
  ra = va_arg(ap, unsigned*);
  sp = va_arg(ap, unsigned*);

  daddr1 = va_arg(ap, double);
  daddr2 = va_arg(ap, double*);
  resaddr = va_arg(ap, double*);

  printf("first  double precision argument is %e\n",daddr1);
  printf("second double precision argument is %e\n",*daddr2);

  regs(gp, ra, sp, daddr1, daddr2, resaddr);
  printf("Back from assembly routine\n");
  printf("gp is 0x%x\n",*gp);
  printf("ra is 0x%x\n",*ra);
  printf("sp is 0x%x\n",*sp);
  printf("result of double precision add is %e\n",*resaddr);

  va_end(ap);
}

Next | Prev | Up | Top | Contents | Index