user302520
user302520

Reputation:

What are the automatic type promotions of variadic function arguments?

Consider the following code snippet:

#include <stdio.h>
#include <stdarg.h>

void display(int num, ...) {
    char c;
    int j;
    va_list ptr;
    va_start(ptr,num);
    for (j= 1; j <= num; j++){
        c = va_arg(ptr, char);
        printf("%c", c);

    }
    va_end(ptr);
}

int main() {
    display(4, 'A', 'a', 'b', 'c');
    return 0;
}

The program gives runtime error because vararg automatically promotes char to int, and i should have used int in this case.

What are all types are permitted when I use vararg, how to know which type to use and avoid such runtime errors.

Upvotes: 7

Views: 5945

Answers (3)

A. K.
A. K.

Reputation: 38156

While using va_arg the char is promoted to int. There are other types(the list given by @R..) which are promoted.

so in order to read it as a char you have to do typecast.

char c = (char) va_arg(ap, int);

For a complete list, please see the 'Default conversions' section in:

http://en.cppreference.com/w/cpp/language/variadic_arguments

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215259

You can use any standard type with va_arg except char, signed char, unsigned char, short, unsigned short, _Bool, and float. It's possible that an implementation defines additional nonstandard types that also have integer conversion rank lower than int, or likewise nonstandard small floating-point types, but you would not need to be aware of these unless you intend to use them, so for practical purposes the list I gave is complete.

Upvotes: 6

Jens Gustedt
Jens Gustedt

Reputation: 78923

another case that the others forgot to mention are pointer types, critical is NULL in particular. Since this could expand to 0 or (void*)0 (or some other weird things) you will not know if the compiler puts an int or a void* in the list. Since these can have different width, this can lead to annoying bugs.

Upvotes: 9

Related Questions