Sized integers (those from stdint.h) are actually typedefs to standard C types. So, the "default arguments promotions" that apply in variadic (varargs) functions such as printf() will be applied to them as well, so that char and short are cast to int (signed or unsigned).
I'm writing a printf-like function that is designed for sized integers. It has a format string that has the size information for all the integers in the variable argument list.
How should I write the varargs querying code, so that it retrieves each argument with its correct size? I guess my function will need to be aware of default argument promotions, but they are compiler/system-dependent, because it depends on whether the system has a 16/32/64 bit int. How can I get the arguments right, in a compiler-independent way?
To determine if some type becomes int, unsigned or stays the same type when passed to a function with ..., code could use _Generic().   (C99 or later)  
By using *1, this mimics the usual promotions seen with f(format, ...). 
Now your printf-like function can determine if the argument was promoted to int, unsigned or left as-is.
#include <stdio.h>
#define PromoType(v) _Generic(v*1, \
  unsigned : "unsigned", \
  int : "int", \
  default: "no change" \
  )
int main(void) {
  int16_t i16;
  puts(PromoType(i16));
  uint16_t u16;
  puts(PromoType(u16));
  int32_t i32;
  puts(PromoType(i32));
  uint32_t u32;
  puts(PromoType(u32));
  int64_t i64;
  puts(PromoType(i64));
  uint64_t u64;
  puts(PromoType(u64));
  return 0;
}
Output
int
int
int
unsigned
no change
no change
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With