如何创建自动检测类型并打印数值的宏?EVAL_TYPE_FORMATER实现求助
适配多类型的assert_equal宏格式字符串实现问题
现有代码
assert_equal宏
#define assert_equal(x, y) do {\ typeof(x) evalx = x;\ typeof(y) evaly = y;\ _assert(evalx == evaly, __LINE__, __FILE__,\ EVAL_TYPE_FORMATER(evalx)" != "EVAL_TYPE_FORMATER(evaly), evalx, evaly\ )\ } while (0)
_assert函数原型
void _assert(bool condition, size_t line, const char* file, char* format, ...);
尝试过的方案及问题
方案1:#if + typeof(失败)
试图用预处理器条件判断类型,但宏展开阶段#if无法处理typeof的动态类型结果,编译直接报错:
#define EVAL_TYPE_FORMATER(exp)\ #if typeof(exp) == char ||\ typeof(exp) == short ||\ typeof(exp) == int\ "%d"\ #elif typeof(exp) == long\ "%ld"\ ...
方案2:_Generic(拼接失败)
改用C11的_Generic做编译期类型匹配,但因宏外层多加了括号,导致返回的格式字符串无法与相邻字面量自动拼接,编译失败:
#define EVAL_TYPE_FORMATER(exp) (_Generic((exp), \ char: "%d", \ short: "%d", \ int: "%d", \ long: "%ld", \ ... ))
更优解决方案
修正_Generic宏写法(去掉多余括号)
C语言支持相邻字符串字面量自动合并,只需去掉EVAL_TYPE_FORMATER宏外层的括号,让_Generic直接返回字符串字面量,即可参与拼接:
#define EVAL_TYPE_FORMATER(exp) _Generic((exp), \ char: "%d", \ short: "%d", \ int: "%d", \ long: "%ld", \ long long: "%lld", \ unsigned char: "%u", \ unsigned short: "%u", \ unsigned int: "%u", \ unsigned long: "%lu", \ unsigned long long: "%llu", \ float: "%f", \ double: "%lf" \ )
此时EVAL_TYPE_FORMATER(evalx)" != "EVAL_TYPE_FORMATER(evaly)会被编译器自动合并为完整格式字符串,比如当evalx为int、evaly为long时,最终会生成"%d != %ld",可直接传入_assert函数使用。
进阶:封装类型匹配逻辑(提高可维护性)
如果需要频繁复用类型格式映射,可以把_Generic的类型匹配逻辑抽成独立宏,减少重复代码:
#define TYPE_FORMAT(exp) _Generic((exp), \ char: "%d", \ short: "%d", \ int: "%d", \ long: "%ld", \ long long: "%lld", \ unsigned char: "%u", \ unsigned short: "%u", \ unsigned int: "%u", \ unsigned long: "%lu", \ unsigned long long: "%llu", \ float: "%f", \ double: "%lf" \ ) #define assert_equal(x, y) do {\ typeof(x) evalx = x;\ typeof(y) evaly = y;\ _assert(evalx == evaly, __LINE__, __FILE__,\ TYPE_FORMAT(evalx) " != " TYPE_FORMAT(evaly), evalx, evaly\ )\ } while (0)
补充说明
- 该方案依赖C11及以上标准的
_Generic特性,需确保编译器支持(如GCC 4.9+、Clang 3.1+、MSVC 2015+)。 - 可根据实际需求扩展
_Generic中的类型映射,覆盖更多基础类型或自定义typedef类型。
内容的提问来源于stack exchange,提问作者Tenobaal
相关产品推荐
相关产品推荐

