Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sized integers and promotions in varargs functions

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?

like image 761
cesss Avatar asked Oct 16 '25 03:10

cesss


1 Answers

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
like image 85
chux - Reinstate Monica Avatar answered Oct 18 '25 19:10

chux - Reinstate Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!