static inline __printf(2, 3)
int dev_err(const struct device *dev, const char *fmt, ...)
{ return 0; }
__printf()
dev_err 的第三个 arg(...) 在做什么以及是什么意思?我能够想象这个函数是某种通用函数。它有什么作用?
static inline __printf(2, 3)
int dev_err(const struct device *dev, const char *fmt, ...)
{ return 0; }
__printf()
dev_err 的第三个 arg(...) 在做什么以及是什么意思?我能够想象这个函数是某种通用函数。它有什么作用?
除了__printf(2,3)
.
函数的这个修饰符(类似于static
orinline
修饰符)告诉编译器它应该使用样式格式说明符检查参数 2 ( fmt
) 处的格式字符串与从参数 3 开始的实际参数。printf
换句话说,调用它:
dev_err (pDev, "%d", 1.0);
会标记警告,因为格式字符串和实际参数不匹配。
...
简单地表示在格式字符串之后有可变数量的参数,类似于它printf
本身的实现方式。C 长期以来一直具有处理变量参数列表的能力,__printf()
修饰符只是为编译器提供了一些额外的信息,以便它可以验证您对函数的使用。
Linux 定义__printf(a, b)
as__attribute__((format(printf, a, b)))
并且 gcc 允许第二种格式按照此处指定 varargs-checking 属性(解释如下):
格式(原型、字符串索引、首先检查):
format 属性指定函数采用 printf、scanf、strftime 或 strfmon 样式参数,这些参数应根据格式字符串进行类型检查。例如,声明:
extern int my_printf (void *my_object, const char *my_format, ...)
__attribute__ ((format (printf, 2, 3)));
导致编译器检查对 my_printf 的调用中的参数是否与 printf 样式格式字符串参数 my_format 保持一致。
在上面的示例中,格式字符串 (my_format) 是函数 my_print 的第二个参数,要检查的参数从第三个参数开始,因此格式属性的正确参数是 2 和 3。
format 属性允许您识别自己的函数,这些函数将格式字符串作为参数,以便 GCC 可以检查对这些函数的调用是否有错误。
至于函数本身的作用,除了返回零之外没有很多:-)
如果您希望实际实现一个真正的dev_err()
功能,它几乎肯定是一个占位符。
__printf
是一个函数,可能在您与编译器一起使用的库中定义,...
意味着dev_err
它需要可变数量的参数,va_args
;