MinGW / Windows / printf format specifiers

From: Chapman Flack <chap(at)anastigmatix(dot)net>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: MinGW / Windows / printf format specifiers
Date: 2016-02-19 04:15:40
Message-ID: 56C696EC.4000305@anastigmatix.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

So I announce a PL/Java 1.5.0-BETA1 with a comment that windows-MSVC
was well tested but that I hadn't found anyone to test windows-mingw,
and behold, what should happen but someone turns up with an interest
in testing the mingw build, so we might have that back in shape as
well for -BETA2.

Haven't run into any showstoppers, but gcc is issuing printf-format
warnings in three places where JNI values of type jint or jlong are
printed.

The cause seems to be that Windows conventions have int = long = int32
(even on 64-bit platforms) and only 'long long' = int64. The Java JNI
headers of course know this, so they type jlong as 'long long', while
jint they type as 'long' - curiously, because they could just call it
int and get the same width. Maybe a habit from a 16-bit C environment?

gcc warns about %ld used with a jlong argument (and it is right,
because for Windows that really should be %lld or %I64d).

It also complains about %d used with a jint argument (a bit spuriously,
because it wants to see %d paired with 'int' while 'jint' is typed as
'long', producing a warning _even though those have the same width_).

I'm familiar with a common way of handling this using a macro like
PRId64 that expands to the correct printf format code on each platform
(printf("My value is %10" PRId64 "\n", v)) ... which then becomes a
potential localization headache because if the format string is the
message key, it's now not the same between platforms.

In my particular case, PL/Java has never had any localization effort
yet, and the only affected sites right now are two debug messages and
one error, not places where the urgency to localize burns hottest.

But if others here have already considered these issues and settled
on a good approach, I'd be happy to not spend time inventing another.

I found some of the printf format specifier differences, Windows to
other platforms, described well in this StackOverflow thread:

http://stackoverflow.com/questions/6299083/cross-platform-printing-of-64-bit-integers-with-printf

And the MinGW wiki has a directly relevant page:

https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/

They provide their own printf that supports %lld (you can get it by
default by defining __USE_MINGW_ANSI_STDIO) ... and, to avoid
spurious compiler warnings, they also define a macro __MINGW_PRINTF_FORMAT
that can be used in __attribute__((__format__ ...))) so gcc's format
checker applies the right checks.

Have issues like this been dealt with in PostgreSQL code before, and did
a favorite approach emerge?

-Chap

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2016-02-19 04:22:01 Re: Relaxing SSL key permission checks
Previous Message Atri Sharma 2016-02-19 03:20:21 Re: about google summer of code 2016