varargs函数中的大小整数和促销

时间:2016-03-28 11:41:17

标签: c variadic-functions

大小整数(来自stdint.h的整数)实际上是标准C类型的typedef。因此,适用于variadic(varargs)函数(如printf())的“默认参数提升”也将应用于它们,因此char和short将转换为int(有符号或无符号)。

我正在编写一个类似printf的函数,专为大小整数而设计。它有一个格式字符串,其中包含变量参数列表中所有整数的大小信息。

我应该如何编写varargs查询代码,以便它以正确的大小检索每个参数?我想我的函数需要知道默认参数提升,但它们是编译器/系统相关的,因为它取决于系统是否具有16/32/64位int。如何以与编译器无关的方式获得正确的参数?

1 个答案:

答案 0 :(得分:3)

要确定some type变为intunsigned或在传递给...的函数时保持相同类型,代码可以使用_Generic()。 (C99或更高版本)

使用*1,这会模仿f(format, ...)所见的常规促销活动。

现在您的类似printf的函数可以确定参数是否已提升为intunsigned或原样保留。

#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;
}

输出

int
int
int
unsigned
no change
no change