使用M*LIB定义自定义类型键的字典时宏参数不足错误排查
问题:M*LIB字典定义编译错误排查
问题场景
我尝试用M*LIB定义一个以自定义类型util_obj_t为键、double为值的字典,代码如下:
DICT_DEF2(dict_util_obj, util_obj_t, (INIT_SET(util_obj_init_set), SET(util_obj_set), CLEAR(util_obj_clear), HASH(util_obj_hash), EQUAL(util_obj_equal)), double)
注:OPLIST中的所有函数均已定义且签名正确
编译错误信息
编译时出现以下错误:
/Volumes/FILES/_proj/sbsc/src/sbsc.c:64:1: error: too few arguments provided to function-like macro invocation 64 | DICT_DEF2(dict_util_obj, util_obj_t, (INIT_SET(util_obj_init_set), SET(util_obj_set), CLEAR(util_obj_clear), HASH(uti ... | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:2192:19: note: expanded from macro 'DICT_DEF2' 2192 | #define DICT_DEF2 M_DICT_DEF2 | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:38:3: note: expanded from macro 'M_DICT_DEF2' 38 | M_DICT_DEF2_AS(name, M_F(name,_t), M_F(name,_it_t), M_F(name,_itref_t), key_type, __VA_ARGS__) | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:52:70: note: expanded from macro 'M_DICT_DEF2_AS' 52 | (name, key_type, __VA_ARGS__, name_t, it_t, itref_t ) )) \ | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:216:9: note: macro 'M_D1CT_DEF2_P2' defined here 216 | #define M_D1CT_DEF2_P2(name, key_type, key_oplist, value_type, value_oplist, dict_t, dict_it_t, it_deref_t) \ | ^ /Volumes/FILES/_proj/sbsc/src/sbsc.c:64:1: error: unknown type name 'M_D1CT_DEF2_P2' 64 | DICT_DEF2(dict_util_obj, util_obj_t, (INIT_SET(util_obj_init_set), SET(util_obj_set), CLEAR(util_obj_clear), HASH(uti ... | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:2192:19: note: expanded from macro 'DICT_DEF2' 2192 | #define DICT_DEF2 M_DICT_DEF2 | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:38:3: note: expanded from macro 'M_DICT_DEF2' 38 | M_DICT_DEF2_AS(name, M_F(name,_t), M_F(name,_it_t), M_F(name,_itref_t), key_type, __VA_ARGS__) | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:50:3: note: expanded from macro 'M_DICT_DEF2_AS' 50 | M_D1CT_DEF2_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ | ^ /Volumes/FILES/_proj/sbsc/extern/mlib/m-dict.h:213:35: note: expanded from macro 'M_D1CT_DEF2_P1' 213 | #define M_D1CT_DEF2_P1(arg) M_ID( M_D1CT_DEF2_P2 arg ) | ^ 2 errors generated.
疑问与诉求
我是C宏新手,搞不清问题出在哪。我觉得调用形式和文档示例一致,但不确定是否需要给double提供OPLIST——文档里用unsigned int时不需要OPLIST就能正常工作,希望能得到排查指导。
问题原因与解决办法
核心原因
M*LIB的DICT_DEF2宏在处理参数时,会通过括号结构识别OPLIST。你的调用中,宏无法正确区分“键的OPLIST”和“值类型”,把double当成了OPLIST的一部分,导致参数数量不匹配,触发编译错误。
解决代码
给double加上空的OPLIST标记(),明确告知宏这是值类型且不需要额外操作函数:
DICT_DEF2(dict_util_obj, util_obj_t, (INIT_SET(util_obj_init_set), SET(util_obj_set), CLEAR(util_obj_clear), HASH(util_obj_hash), EQUAL(util_obj_equal)), double, ())
原理说明
- 自定义类型必须提供包含HASH、EQUAL等操作的OPLIST;
- 内置基本类型(如
unsigned int、double)有默认OPLIST实现,但当它作为值类型且前面已经存在带括号的键OPLIST时,必须用空括号()占位,否则宏会解析错误; - 文档中
unsigned int的示例可能是作为键类型使用,此时不需要后续占位;而你的场景中double是值类型,前面已有键的OPLIST,必须显式加空括号完成宏的参数匹配。
内容的提问来源于stack exchange,提问作者sporkl
相关产品推荐
相关产品推荐

