文章

__attribute__((format)) 说明

在学习存储引擎编写的时候,发现一个错误处理的函数的写法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 __attribute__((__format__(__printf__, 4, 0))) static bool
 try_vsprintf(char **buffer, char *buffer_end, size_t *chars,
             const char *format, va_list ap) {
  size_t sz = (size_t)(buffer_end - *buffer);
  int rc = vsnprintf(*buffer, sz, format, ap);
  if (rc < 0 ||          // encoding
      (size_t)rc >= sz)  // space
    return false;
  *buffer += rc;
  *chars += (size_t)rc;
  return true;
 }
 __attribute__((__format__(__printf__, 4, 5))) static bool try_sprintf(
    char **buffer, char *buffer_end, size_t *chars,
    const char *format, ...) {
  va_list ap;
  va_start(ap, format);
  bool ret = try_vsprintf(buffer, buffer_end, chars, format, ap);
  va_end(ap);
  return ret;
 }

查询了官方的文档可以看到,这个是可以对我们自己写的函数有类似于 printf 这种的会做静态检查,第一个参数就是你的函数和哪个函数的行为类似,是 printf 还是 scanf, 第二个参数就是格式字符串的索引,下标从 1 开始计算,第三个参数就是要检查的第一个占位符的位置,如果写 0 的话,则表示只检查格式字符串是否满足规范,不会对后续的字符串进行检查,这种就是针对于变参类型的函数不确定第一个字符串的位置来确定的。

本文由作者按照 CC BY 4.0 进行授权