__va_sizeof__ keyword

According to the ANSI-C specification, you must promote character arguments in open parameter lists to int. The use of char in the va_arg macro to access this parameter may not work as per the ANSI-C specification.

Listing: Inappropriate use of char with the va_arg macro


int f(int n, ...) {
  int res;

  va_list l= va_start(n, int);

  res= va_arg(l, char); /* should be va_arg(l, int) */

  va_end(l);

  return res;

}

void main(void) {

  char c=2;

  int res=f(1,c);

}

With the __va_sizeof__ operator, the va_arg macro is written the way that f() returns 2.

A safe implementation of the f function is to use va_arg(l, int) instead of va_arg(l, char).

The __va_sizeof__ unary operator, which is used exactly as the sizeof keyword, returns the size of its argument after promotion as in an open parameter list.

Listing: __va_sizeof__ examples


__va_sizeof__(char)  == sizeof (int)
__va_sizeof__(float) == sizeof (double)

struct A { char a; };

__va_sizeof__(struct A) >= 1 (1 if the target needs no padding bytes)
Note: It is not possible in ANSI-C to distinguish a 1-byte structure without alignment or padding from a character variable in a va_arg macro. These need a different space on the open parameter calls stack for some processors.