bug-gnulib
[Top][All Lists]
Advanced

[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

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]