C语言 __typeof variables and printf



如果我定义一个通用宏,使用__typeof__/typeof,是否有任何方法也可以选择printf转换说明符,以通用的方式?

我的意思是,例如:

#define max(a,b) 
 ({ typeof (a) _a = (a); 
    typeof (b) _b = (b); 
    DEBUG(( "%" __PRI_TYPE_PREFIX(a) > "%" __PRI_TYPE_PREFIX(b) "?", _a, _b))   <-- hypothetical
    _a > _b ? _a : _b; })

您可以使用C11的_Generic功能来完成此操作,例如

#define printf_dec_format(x) _Generic((x), 
    char: "%c", 
    signed char: "%hhd", 
    unsigned char: "%hhu", 
    signed short: "%hd", 
    unsigned short: "%hu", 
    signed int: "%d", 
    unsigned int: "%u", 
    long int: "%ld", 
    unsigned long int: "%lu", 
    long long int: "%lld", 
    unsigned long long int: "%llu", 
    float: "%f", 
    double: "%f", 
    long double: "%Lf", 
    char *: "%s", 
    void *: "%p")
#define print(x) printf(printf_dec_format(x), x)

(示例取自:Rob的编程博客)

#include <stdio.h>
#define FMT(_pre_, x, _post_) _Generic((x), 
  char: _pre_ "%c" _post_, 
  int: _pre_ "%d" _post_, 
  long: _pre_ "%ld" _post_)
int main()
{
  int x = 42;
  long y = 432144312432321;
  printf(FMT("foo: ", x, "n"), x);
  printf(FMT("bar: ", y, "n"), y);
  return 0;
}

前和后的东西是有点丑,但我还没有找到一个更好的方法。我们不能在C预处理器中依赖字符串连接,因为_Generic是由编译器求值的,太晚了。

例如,使用C11 _Generic(必须完成完整检查):

#define DEBUG_INT(a, b)     DEBUG("%d %d?", (a), (b))
#define DEBUG_DOUBLE(a, b)  DEBUG("%f %f?", (a), (b))
#define FAIL(a, b)          assert(0)
#define max(a,b) 
 ({ typeof (a) _a = (a); 
    typeof (b) _b = (b); 
    _Generic((_a), int: DEBUG_INT, double: DEBUG_DOUBLE, default: FAIL))(_a, _b); 
    _a > _b ? _a : _b; })

或使用__builtin_types_compatible_p gcc扩展:

#define max(a,b) 
 ({ typeof (a) _a = (a); 
    typeof (b) _b = (b); 
    if (__builtin_types_compatible_p(typeof(int), _a) && __builtin_types_compatible_p(typeof(int), _a))  DEBUG_INT(_a, _b);  
    else if  (__builtin_types_compatible_p(typeof(double), _a) && __builtin_types_compatible_p(typeof(double), _a))  DEBUG_DOUBLE(_a, _b); 
    else FAIL(_a, _b);
    _a > _b ? _a : _b; })

最新更新