[libvirt] [PATCH] Avoid passing NULL to printf %s specifier
Jim Meyering
jim at meyering.net
Thu Jan 15 11:17:21 UTC 2009
john.levon at sun.com wrote:
> Avoid passing NULL to printf %s specifier
This looks fine.
Thanks!
> diff --git a/src/internal.h b/src/internal.h
> --- a/src/internal.h
> +++ b/src/internal.h
> @@ -115,6 +115,8 @@
> #define ATTRIBUTE_RETURN_CHECK
> #endif /* __GNUC__ */
>
> +#define NULLSTR(a) ((a) ? (a) : "(null)")
However, to prevent overzealous developers from accidentally
applying NULLSTR to a non-char*, how about using an inline
function instead? e.g.,
static inline const char *nullstr(const char *s) { return s ? s : "(null)"; }
Then if I accidentally use "nullstr(some_int_var)", the compiler will
catch it, rather than masking the real error at run time.
Some macro abuses would result in warnings, but at least NULLSTR(0)
would mistakenly hide a real error. Whoops. the static inline
function also masks the problem with a literal "0".
A little experimentation shows that using something
like this does most of what I want:
#define NULLSTR(s) \
((void)verify_true(sizeof *(s) == sizeof (char)), \
(s) ? (s) : "(null)")
That verify_true use ensures (at compile time) that "s" is a pointer
to something "char"-sized. verify_true is defined in gnulib's
#include <verify.h>, which is already used by libvirt.
Then, even NULLSTR(0) is diagnosed at compile time.
For the record, note that this usage does *not* trigger a failure:
char i[10] = "abcdef";
printf ("%s", NULLSTR(i));
However, gcc -Wall does print a warning:
warning: the address of 'i' will always evaluate as 'true'
but that's moot, because there's no reason ever to use NULLSTR
on such a variable.
More information about the libvir-list
mailing list