[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Confusion about gnulib asprintf attribute annotation...
From: |
Eric Blake |
Subject: |
Re: Confusion about gnulib asprintf attribute annotation... |
Date: |
Wed, 30 Mar 2011 14:10:29 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.9 |
[adding bug-gnulib, to get Bruno's take on this]
On 03/29/2011 05:14 AM, Daniel P. Berrange wrote:
> Hey Eric,
>
> In libvirt we annotate virAsprintf() with '__gnu_printf__' to ensure
> gcc uses the GNU printf specifiers to get %lld support.
>
> I've just noticed that the actual GNULIB asprintf() function though
> is only using '__printf__' which means it will use the Win32 specifiers
> on GCC >= 4.4. This seems not right to me, since IIRC asprintf() is
> providing a full GNU compatible implementation AFAIK (libvirt certainly
> thinks it is, hence our virAsprintf annotation).
I see this in 'info gcc':
The parameter ARCHETYPE determines how the format string is
interpreted, and should be `printf', `scanf', `strftime',
`gnu_printf', `gnu_scanf', `gnu_strftime' or `strfmon'. (You can
also use `__printf__', `__scanf__', `__strftime__' or
`__strfmon__'.) On MinGW targets, `ms_printf', `ms_scanf', and
`ms_strftime' are also present. ARCHTYPE values such as `printf'
refer to the formats accepted by the system's C run-time library,
while `gnu_' values always refer to the formats accepted by the
GNU C Library. On Microsoft Windows targets, `ms_' values refer
to the formats accepted by the `msvcrt.dll' library.
We only accept a subset of __gnu_printf__ in the gnulib replacement (for
example, gnulib supports %Id on glibc, but not elsewhere, even though
using attribute __gnu_printf__ would not warn about use of %Id). But
you are also right that __printf__ devolves to __gnu_printf__ on glibc
and to __ms_printf__ on mingw, and that __ms_printf__ warns for %lld
even though the gnulib replacements guarantee that it is valid. I'd
rather go for __gnu_printf__ everywhere (at the expense of missed
warnings) than going for __printf__ and getting spurious warnings on
mingw about the very things that the gnulib *printf modules end up
working around.
> The thing I'm looking at is gnulib/lib/stdio.h.in which has:
>
> #define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument)
> \
> _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter,
> first_argument))
>
> Whereas I'd expect it to look more like this if gnulib has a GNU compatible
> replacement asprintf()
>
> #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
> # define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter,
> first_argument) \
> _GL_ATTRIBUTE_FORMAT ((__gnu_printf__, formatstring_parameter,
> first_argument))
> #else
> # define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter,
> first_argument) \
> _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter,
> first_argument))
> #endif
>
> Except this affects all the *printf() variants listed in stdio.h.in, and
> from previous discussions, only asprintf() seemed to be GNU compatible
>
> http://www.redhat.com/archives/libvir-list/2010-August/msg00447.html
Right; the various *printf-posix modules provide everything, but the
*printf counterparts vary in how much they provide (asprintf pretty much
provides everything, since mingw lacks it to begin with, but printf and
sprintf still don't understand %lld because they didn't need to pull in
the full asprintf).
>
> So maybe it instead needs a _GL_ATTRIBUTE_FORMAT_GNU_PRINTF like
>
> #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
> # define _GL_ATTRIBUTE_FORMAT_GNU_PRINTF(formatstring_parameter,
> first_argument) \
> _GL_ATTRIBUTE_FORMAT ((__gnu_printf__, formatstring_parameter,
> first_argument))
> #else
> # define _GL_ATTRIBUTE_FORMAT_GNU_PRINTF(formatstring_parameter,
> first_argument) \
> _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter,
> first_argument))
> #endif
>
> and then change asprintf() to use _GL_ATTRIBUTE_FORMAT_GNU_PRINTF ?
Hmm, sounds like we might really want an explicit __gnu_printf__ on
asprintf, regardless of whether it was asprintf or asprintf-posix
module; whereas the printf declaration gets __printf__ for the printf
module and __gnu_printf__ for the printf-posix module. Which means
_GL_ATTRIBUTE_FORMAT_GNU_PRINTF has to be defined first, then something
like:
#if posix-modules
# define _GL_ATTRIBUTE_FORMAT_PRINTF _GL_ATTRIBUTE_FORMAT_GNU_PRINTF
#else
# define _GL_ATTRIBUTE_FORMAT_PRINTF __printf__
#endif
But I agree that it could use some cleanup.
--
Eric Blake address@hidden +1-801-349-2682
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
- Re: Confusion about gnulib asprintf attribute annotation...,
Eric Blake <=