__printflike__修饰符

har*_*ari 5 c printf modifier

究竟什么是"__printflike__修饰符"?这个术语是什么意思?

Ben*_*son 8

猜测它告诉编译器你正在使用一个函数接受参数的形式[anything, ] format, ...,其中format, ...部分看起来像参数printf.该__printflike__属性允许编译器根据字符串格式测试参数列表中的类型.当您编写类似函数log(format, ...)vsprintf在将字符串发送到某些特殊日志界面之前将格式化工作从属于通常的标准库函数时,就会出现这种情况.

如果您正在使用GCC,那么#define您的项目可能就像:

#define __printflike__ __attribute__((format(printf, 1, 2)))
Run Code Online (Sandbox Code Playgroud)

1, 2这意味着format, ...出现在位置1和2.


Jon*_*ler 5

我的错误报告库中有一个函数,其标题中的声明如下:

extern void err_logmsg(FILE *fp, int flags, int estat, const char *format, ...)
                       PRINTFLIKE(4,5);
Run Code Online (Sandbox Code Playgroud)

PRINTFLIKE 是大写的,这样当我不使用 GCC 时我可以将它定义为空。这种用法表示前三个参数没有什么特别的,但第四个参数是一个格式字符串,类似于使用的格式字符串printf()(实际上,在内部,它被传递给vfprintf()),并且与其对应的参数(使用格式字符串格式化)开始与第五个参数。

这意味着如果我输入:

err_logmsg(stdout, ERR_ABORT, 1, "%s: %d\n", errno, strerror(errno));
Run Code Online (Sandbox Code Playgroud)

我会得到一个编译错误,因为errnois anintstrerror(errno)返回一个指向字符串的指针。我可以通过更改格式字符串或第五个和第六个参数来修复错误。(ERR_ABORT 是在声明 的同一标头中定义的一组标志err_logmsg()。)

PRINTFLIKE 宏中有两个数字,因为格式字符串和格式字符串使用的第一个参数之间可能存在其他参数。例如,替代函数可以是:

extern void err_writer(FILE *fp, const char *format, int flags, int estat, ...)
                       PRINTFLIKE(2,5);
Run Code Online (Sandbox Code Playgroud)

这告诉编译器格式字符串是第二个参数,但格式化的相应参数仍然从第五个参数开始出现。

此代码的头文件包含以下行:

#ifdef __GNUC__
#define PRINTFLIKE(n,m) __attribute__((format(printf,n,m)))
#define NORETURN()      __attribute__((noreturn))
#else
#define PRINTFLIKE(n,m) /* If only */
#define NORETURN()      /* If only */
#endif /* __GNUC__ */
Run Code Online (Sandbox Code Playgroud)