C预处理器多替换宏定义使用疑问及printf报错解析
关于ALLOCSET_SMALL_SIZES宏的用法解析
问题场景
用户尝试用以下代码调用ALLOCSET_SMALL_SIZES宏:
printf("%d", ALLOCSET_SMALL_SIZES);
结果收到编译器警告:
warning: too many arguments for format [-Wformat-extra-args]
且程序输出值为0。
宏定义说明
对应的宏定义(注释已翻译为中文):
/* * 针对"小型"上下文推荐的内存分配参数,这类上下文预计不会存储大量数据 * (例如,存储查询计划的上下文)。 */ #define ALLOCSET_SMALL_MINSIZE 0 #define ALLOCSET_SMALL_INITSIZE (1 * 1024) #define ALLOCSET_SMALL_MAXSIZE (8 * 1024) #define ALLOCSET_SMALL_SIZES \ ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
错误原因
ALLOCSET_SMALL_SIZES宏展开后是三个用逗号分隔的数值:0, 1024, 8192。当把它放到printf的参数里时,实际代码会变成:
printf("%d", 0, 1024, 8192);
而printf的%d格式符只需要一个整数参数,后面的1024和8192属于多余参数,因此编译器抛出警告。程序输出0是因为printf只会读取第一个参数,剩下的参数被直接忽略。
正确用法
这个宏的设计目的是批量传递三个内存分配参数,专门给接收size_t, size_t, size_t三个参数的函数使用。比如有这样的函数:
void foo(size_t min_size, size_t init_size, size_t max_size) { // 处理内存分配相关逻辑 }
调用时直接写:
foo(ALLOCSET_SMALL_SIZES);
宏展开后就会变成:
foo(0, 1024, 8192);
完美匹配函数的参数列表,这才是它的正确使用方式。
内容的提问来源于stack exchange,提问作者jian
相关产品推荐
相关产品推荐

