sbhatla February 2016

What is the use of __attribute__ (format) in C to define a function?

I came across this line of code in a C project, and I did not understand it.

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

The GNU website does not explain it clearly (https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes)

What is the purpose of __attribute__ ((format ()) and how should it be used?

Answers


Dietrich Epp February 2016

So, the fmt and args parameters just tell you which parameter has the format, and which parameter has the arguments.

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

So in this case, the correct attribute is:

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

If you have a longer function declaration...

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


Jonathan Leffler February 2016

I have a header stderr.h, which amongst other things contains the stanza:

#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 */

and also contains declarations such as:

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);

The NORETURN is another piece of conditional compilati

Post Status

Asked in February 2016
Viewed 3,370 times
Voted 6
Answered 2 times

Search




Leave an answer