user2559503
user2559503

Reputation: 289

va_arg gives Runtime Error

I'm trying to write a small function that takes a format string and some variadic numeric parameters. The format string takes various characters denoting different numeric types (c for char, i for int, d for double, etc) and then for each character in the string takes a number of that type. It then returns the sum of all of these numbers. An example call would look like this:

addEm("cid", 'A', 4, 5.0)

This would return 74, using the ascii code for 'A' in the calculation

The function looks like this:

double addEm(char *format, ...) {
   va_list params;
   va_start(params,format);
   double ret=0;
   while(*format) {
      switch(*format++) {
         case 'c':
            ret+=(double)(va_arg(params, char));
            break;
         case 'd':
            ret+=va_arg(params, double);
            break;
         case 'i':
            ret+=(double)(va_arg(params, int));
            break;
         case 's':
            ret+=(double)(va_arg(params, short));
            break;
         case 'f':
            ret+=(double)(va_arg(params, float));
            break;
      } 
   }
   va_end(params);
   return ret;
}

But when I run a call such as the one above it produces an error, and I can't seem to figure out why. Can anyone see what I'm doing wrong? Thanks!

Upvotes: 2

Views: 388

Answers (1)

Lee Duhem
Lee Duhem

Reputation: 15121

Try this:

double addEm(char *format, ...) {
    va_list params;
    va_start(params,format);
    double ret=0;
    while(*format) {
        switch(*format++) {
            case 'c':
                ret+=(double)(va_arg(params, int));
                break;
            case 'd':
                ret+=va_arg(params, double);
                break;
            case 'i':
                ret+=(double)(va_arg(params, int));
                break;
            case 's':
                ret+=(double)(va_arg(params, int));
                break;
            case 'f':
                ret+=(double)(va_arg(params, double));
                break;
        } 
    }
    va_end(params);
    return ret;
}

Here are some gcc warnings that may be helpful:

t038.c:12:19: warning: ‘char’ is promoted to ‘int’ when passed through ‘...’ [enabled by default]
t038.c:12:19: note: (so you should pass ‘int’ not ‘char’ to ‘va_arg’)
t038.c:12:19: note: if this code is reached, the program will abort
t038.c:21:19: warning: ‘short int’ is promoted to ‘int’ when passed through ‘...’ [enabled by default]
t038.c:21:19: note: if this code is reached, the program will abort
t038.c:24:19: warning: ‘float’ is promoted to ‘double’ when passed through ‘...’ [enabled by default]
t038.c:24:19: note: if this code is reached, the program will abort

Upvotes: 2

Related Questions