As we all know and love (or hate), GCC has the capability of issuing warnings when you attempt to use the printf() family of functions with mismatched type specifications. In our code, we have a number of utility functions of the form:
int zzzprintf(DataType *dt, const char *format, ...) {
va_list args;
va_start(args, format);
int status = vprintf(dt->buf, format, args);
va_end(args);
return status
}
What I’d like to see is the same set of warning semantics around the zzzprintf() function, such that if you, say call:
int64_t id64;
zzzprintf(dt, "Hello, %dn", id64);
you get the warning:
/tmp/foo.c: In function ‘main’:
/tmp/foo.c:7:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int64_t’ {aka ‘long int’} [-Wformat=]
zzzprintf("Hello %dn", id64);
~^ ~~
%ld
Note: I’m not asking for enhancements to the GCC compiler. I’m looking for some way of telling the compiler to expect this behaviour, through a #pragma or the like. We are currently using gcc-8.4.0, and do not have the capability of easily upgrading our gcc, since we are locked in at Ubuntu 18.04 for the time being.
2
Answers
GCC supports Function Attributes including one to mimic
printf
-like (orscanf
,strftime
, orstrfmon
) checking,format
. You can use it by declaring your function like so in the appropriate header:which makes all source files including that header process the arguments using the compiler-checks associated with
printf
.As the link at the top indicates, this has been supported since at least GCC 4.7.2, so your compiler restrictions should not pose an issue.
This is a minor amplification of ShadowRanger‘s answer:
I sometimes use compilers other than GCC on some of my target platforms, so I use a macro to encapsulate the functionality.
Since I develop with GCC, the error checking works on my development platforms, and I rely on that to protect me on other platforms. Life got easier since I don’t work with any 32-bit platforms any more.