为了账号安全,请及时绑定邮箱和手机立即绑定

编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配

标签:
C++

背景

在输出日志时 被 RUNLOG_DEBUG("%s,%d", para_int, para_str.c_str()) 坑过, 才知道 能校验 格式化字符串和 字段本身是否匹配 的重要性;

参考文献:https://www.cnblogs.com/marvin-notes/p/4482805.html 感谢原作者

方法

attribute format 该属性 可以给被声明的 函数 加上 类似 printf /scanf 的特征, 能用于 编译器检查 函数声明和时间调用参数直接的 格式化字符串是否 匹配; GNU CC需要使用 –Wall 才能使用

语法: format (archetype, string-index, first-to-check)

archetype :  printf, scanf, strftime或strfmon,  表示按照那种风格进行检查

string-index: 传入参数的第几个参数是格式化字符串, 就是 "%s,%d" 的下标(从1 开始)

first-to-check: 指定从 函数的 第几个参数开始 校验

实例:

__attribute__((format(printf,m,n)))

m:第几个参数为格式化字符串(format string)

n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几.这里需要注意,有时函数参数里还有“隐身”的,如C++的类成员函数的第一个参数实际上是"隐身"的"this"指针;

代码实例

#include <stdarg.h>

#include <string>

#include <stdio.h>

using namespace std;

#define mm_p(fmt, args...) myprint(fmt, args)

void myprint(const char *fmt,...)  __attribute__((format(printf,1,2)));

void myprint(const char *fmt,...)

{

    va_list ap; 

    va_start(ap, fmt);

    vprintf(fmt,ap);

    va_end(ap);

}

struct ss

{

public:

    void pri(const char* fmt, ...) __attribute__((format(printf,2,3)))

    {   

    }   

};

int main()

{

    mm_p("dfjkaj[%d][%s]\n",123,456);

    myprint("dfjkaj[%d][%d]\n",123,456);

    ss s;

    s.pri("%s[%s", "dd",456);

}

g++ -Wall test_var.cpp -o test_var

test_var.cpp: In function 'int main()':

test_var.cpp:27: warning: format '%s' expects type 'char*', but argument 3 has type 'int'

test_var.cpp:31: warning: format '%s' expects type 'char*', but argument 4 has type 'int'

©著作权归作者所有:来自51CTO博客作者qdqade的原创作品,如需转载,请注明出处,否则将追究法律责任

格式化校验杂记


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消