如何让自定义zzzprintf函数触发GCC的printf格式类型匹配警告?
实现自定义printf风格函数的格式匹配警告
要让GCC 8.4对自定义的zzzprintf函数触发格式说明与参数类型不匹配的警告,核心是利用GCC提供的**format函数属性**,它能让编译器把你的函数当作标准printf系列函数来做格式检查。
方法1:直接在函数声明/定义中添加属性
在zzzprintf的声明或定义里加上__attribute__((format(printf, 2, 3))),参数含义:
printf:表示遵循标准printf的格式规则2:格式字符串是函数的第2个参数(第一个是DataType *dt)3:可变参数从第3个参数开始
修改后的函数定义示例:
#include <stdarg.h> #include <stdio.h> typedef struct { FILE *buf; // 假设dt->buf是FILE*类型,对应vprintf的参数要求 } DataType; int zzzprintf(DataType *dt, const char *format, ...) __attribute__((format(printf, 2, 3))) { va_list args; va_start(args, format); int status = vprintf(dt->buf, format, args); va_end(args); return status; }
方法2:用#pragma批量设置属性
如果不想直接修改函数代码,可以用#pragma GCC attribute来给指定函数添加属性:
#include <stdarg.h> #include <stdio.h> typedef struct { FILE *buf; } DataType; #pragma GCC attribute push (__attribute__((format(printf, 2, 3))), zzzprintf) int zzzprintf(DataType *dt, const char *format, ...) { va_list args; va_start(args, format); int status = vprintf(dt->buf, format, args); va_end(args); return status; } #pragma GCC attribute pop
验证效果
编译时确保开启-Wformat警告(GCC 8.4默认已开启,若手动关闭需重新添加),当调用:
#include <stdint.h> int main() { DataType dt = {stdout}; int64_t id64 = 123; zzzprintf(&dt, "Hello, %d\n", id64); return 0; }
会触发预期的警告:
/tmp/foo.c: In function ‘main’: /tmp/foo.c:7:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int64_t’ {aka ‘long int’} [-Wformat=] zzzprintf(&dt, "Hello, %d\n", id64); ~^ ~~~~ %ld
内容的提问来源于stack exchange,提问作者Ken P
相关产品推荐
相关产品推荐

