在C中使用__attribute __(格式)来定义函数有什么用?

时间:2016-02-08 21:13:15

标签: c gcc

我在C项目中遇到过这行代码,我不明白。

#define FMT_CHK(fmt, args)  __attribute__ ((format (printf, fmt, args)))

GNU网站没有明确解释(custom sequence string as sql identity column

__attribute__ ((format ())的目的是什么?如何使用?

3 个答案:

答案 0 :(得分:5)

因此,fmtargs参数只是告诉您哪个参数具有格式,哪个参数具有参数。

void myprintf(const char *fmt, ...);
//            ^^ fmt = arg#1
//                             ^^ args = arg#2...

所以在这种情况下,正确的属性是:

__attribute__((format(printf, 1, 2)))

如果您有更长的功能声明......

void myprintf(obj *x, const char *fmt, int level, ...)
//                    ^^ format: arg#2
//                                                ^^ args: arg#4...
    __attribute__((format(printf, 2, 4)));

答案 1 :(得分:0)

我有一个标题stderr.h,其中包含节:

#if !defined(PRINTFLIKE)
#if defined(__GNUC__)
#define PRINTFLIKE(n,m) __attribute__((format(printf,n,m)))
#else
#define PRINTFLIKE(n,m) /* If only */
#endif /* __GNUC__ */
#endif /* PRINTFLIKE */

并且还包含声明,例如:

extern NORETURN void err_abort(const char *format, ...) PRINTFLIKE(1,2);
extern NORETURN void err_error(const char *format, ...) PRINTFLIKE(1,2);
extern NORETURN void err_error1(const char *s1);
extern NORETURN void err_error2(const char *s1, const char *s2);
extern NORETURN void err_help(const char *use_str, const char *hlp_str);
extern NORETURN void err_helplist(const char *use_str, const char * const *help_list);
extern NORETURN void err_internal(const char *function, const char *format, ...) PRINTFLIKE(2,3);
extern NORETURN void err_syserr(const char *format, ...) PRINTFLIKE(1,2);
extern NORETURN void err_syserr1(const char *s1);
extern NORETURN void err_syserr2(const char *s1, const char *s2);
extern NORETURN void err_syserror(int errnum, const char *format, ...) PRINTFLIKE(2,3);

extern void err_logmsg(FILE *fp, int flags, int estat, const char *format, ...) PRINTFLIKE(4,5);
extern void err_print(int flags, int estat, const char *format, va_list args);
extern void err_printversion(const char *program, const char *verinfo);
extern void err_remark(const char *format, ...) PRINTFLIKE(1,2);
extern void err_remark1(const char *s1);
extern void err_remark2(const char *s1, const char *s2);
extern void err_report(int flags, int estat, const char *format, ...) PRINTFLIKE(3,4);
extern void err_sysrem(const char *format, ...) PRINTFLIKE(1,2);
extern void err_sysrem1(const char *s1);
extern void err_sysrem2(const char *s1, const char *s2);
extern void err_sysremark(int errnum, const char *format, ...) PRINTFLIKE(2,3);

NORETURN是另一条条件编译,表示这些函数在调用后不会返回。标准C(ISO / IEC 9899:2011)具有内置机制 - _Noreturn - 可以与支持C11的编译器一起使用,测试稍微复杂一些。

#if !defined(NORETURN)
#if __STDC_VERSION__ >= 201112L
#define NORETURN      _Noreturn
#elif defined(__GNUC__)
#define NORETURN      __attribute__((noreturn))
#else
#define NORETURN      /* If only */
#endif /* __STDC_VERSION__ || __GNUC__ */
#endif /* NORETURN */

注意当编译器声称不是GCC(__GNUC__)时,该机制如何不受影响。除非您愿意将自己专门与GCC联系起来,否则必须遵循以下保护代码。

答案 2 :(得分:0)

gcc页面中的报价:

  

format属性指定一个函数使用printf,scanf,strftime或strfmon样式参数,这些参数应根据格式字符串进行类型检查。

__attribute__ ((format (printf, format_param, arg_list))

gcc将帮助您在编译期间检查arg_list类型是否与format_param相对应。