Web lists-archives.com

Re: [Mingw-users] snprintf and __USE_MINGW_ANSI_STDIO

Hash: SHA1

On 16/11/16 18:28, Burkhardt, Glenn B        UTAS wrote:
> On 16/11/16 13:50, Burkhardt, Glenn B        UTAS wrote:
>> It looks like "snprintf" and friends don't have the same
>> definitions to use the ANSI stdio functions like printf, fprintf,
>> and sprintf do. The result is that if __USE_MINGW_ANSI_STDIO is
>> defined, and -Wall is used, there are compile time warnings if
>> specifications like "%lld" are used.
> On Wed 11/16/2016 11:28, Keith Marshall wrote:
>> This is nothing whatsoever to do with __USE_MINGW_ANSI_STDIO, 
>> (which you really SHOULDN'T define yourself, BTW; use appropriate
>>  _POSIX_C_SOURCE, or _XOPEN_SOURCE definitions instead).  This
>> is just evidence of the inherent dumbness of GCC's printf format 
>> warnings.
> I have to disagree with you.  The problem is the omission of the 
> correct definition for "snprintf" with __USE_MINGW_ANSI_STDIO 
> defined.

No, it isn't ... at least not entirely.

> It works for "printf", and "sprintf".

Again, no it doesn't ... if you compile your code as C++, you will see
those -Wformat messages, regardless.

> This small program:
> #define __USE_MINGW_ANSI_STDIO 1

That's just asking for trouble; it may work (fortuitously) today, but
I could change the semantics associated with the interpretation of this
INTERNALLY RESERVED macro tomorrow, and break your code, and I will not
feel the slightest remorse over your problem.  Use _POSIX_C_SOURCE, or
_XOPEN_SOURCE, (or even _GNU_SOURCE), to make your usage safe.

> #include <stdio.h>
> int main() { long long x = 0x100000000L; char buff[128];
> printf("%lld\n", x); sprintf(buff, "%lld\n", x); printf("%s",
> buff); snprintf(buff, sizeof(buff), "%lld\n", x); printf("%s",
> buff);
> return 0; }
> gives these warnings: $ gcc -g -Wall tt.c -o tt tt.c: In function
> 'main': tt.c:12:5: warning: unknown conversion type character 'l'
> in format [-Wformat] tt.c:12:5: warning: too many arguments for
> format [-Wformat-extra-args]

And I get the same diagnostics, repeated for each of the printf() and
sprintf() calls too, if I add -xc++ to compile your simple program as
if it were C++ code.

> But the "snprintf" call works properly.  The output is: 4294967296 
> 4294967296 4294967296

Of course it does; the implementation correctly interprets both the "ll"
and the "I64" format modifiers, regardless of any bogus assumptions made
by GCC/G++ at compile time.

> Call me fastidious, but I find that compiler warnings often alert
> me to real errors in the code.  False positives waste my time.

Right; and -Wformat is a known source of false positives.

> BTW, the correct format specifiers for int64_t, viz, PRId64, are 
> wrong when using __USE_MINGW_ANSI_STDIO.  That's another bug.

No, it is not.  The implementation understands "I64d", (which is what
PRId64 represents), to mean IDENTICALLY the same as "lld"; this is
correct BY DESIGN, so it certainly is not a bug.  In fact, if you use
"%" PRId64 in your example program, the bogus -Wformat messages go away;
(of course, you do need to define __STDC_FORMAT_MACROS, before including
<inttypes.h>, to make the C++ case work).

> Also, for what it's worth, this all works properly with the
> headers from the MinGW-w64 fork of the MinGW code, and on every
> Linux system I use.

Whatever behaviour you observe on Linux isn't remotely germane to any
discussion of MinGW behaviour; OTOH, if you believe that the mingw-w64
folks have a solution, which works equally well for BOTH C and C++, and
you can offer me a patch, I will certainly consider it.

- -- 

Public key available from keys.gnupg.net
Key fingerprint: C19E C018 1547 DE50 E1D4 8F53 C0AD 36C6 347E 5A3F
Version: GnuPG v2.0.20 (GNU/Linux)


MinGW-users mailing list

This list observes the Etiquette found at 
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

You may change your MinGW Account Options or unsubscribe at:
Also: mailto:mingw-users-request@xxxxxxxxxxxxxxxxxxxxx?subject=unsubscribe