Web lists-archives.com

Re: [Mingw-users] bizarre problem, need help from a mingw developer

On 09-Mar-2016 13:02, Keith Marshall wrote:
> On 09/03/16 20:03, mathog wrote:
>>> (My own
>>> > preference is to use a gcc option, such as -ansi or -posix, or any of
>>> > the -std= options which implies __STRICT_ANSI__
>> You mean like: -std=c99  ???
>> That does not work, at least on the mingw I have installed.  With NO
>> flags one gets the C99 behavior:
>>> > gcc -o printf_bug printf_bug.c
>>> > printf_bug
>> val 1.000000
>> esc 0.000000 cos 1.000000 sin 0.000000 -sin 0.000000 -cos -1.000000
>> esc 0.000000 cos 1.000000 sin 0.000000 -sin 0.000000 -cos -1.000000
> No.  You get the MSVCRT.DLL printf() behaviour, which is NOT the same 
> as
> C99 behaviour; it just happens that your test case is inadequate to
> discriminate, because MSVC doesn't provide a distinct implementation of
> long doubles, (their so-called long doubles are 64-bit, and identically
> equivalent to their 64-bit doubles), whereas in GCC, a long double is
> 80-bits, while double is 64-bits, (identical to MSVC's double).

I get it, I think. The situation is the following...

For this code:

   double val=1.0;

(1) With the default language setting the compiler passes "%lf\n" and a 
64 bit double to _printf().  If nothing else is specified the linker 
uses a _printf() from MSVCRT.  That library interprets the "%lf" to mean 
long double, which it takes to be 64 bit.  So "1.0" is emitted.  
Accidentally it is the correct value, with the two mistakes (it isn't 
long double, long double isn't 64 bits) cancelling each other out.

(2) For the -std=c99 case the compiler still passes "%lf\n" and a 64 bit 
double, but in this case the function which receives it is provided by 
mingw.  It also interprets "%lf" to mean long double.  However it 
expects the value to be a gnu long double of 80 bits. Consequently it 
reads 80 bytes instead of 64, which results in the printing of an 
incorrect value.

(3) When poppler is linked to an object prepared as in (1) something 
carried in the library causes the mingw variant of _printf() to be used 
and not the MSVCRT one, and again the wrong value is emitted, as in (2).

> The bottom line is that MSDN says that "%lf" refers to a long double,
> and __mingw_printf() interprets that to mean a GCC long double.

According to the C and C++ language standards that is wrong and has been 
for 15 years or so.  Don't modern Microsoft development environments now 
use "%lf" in compliance with the C/C++ language standards?  The 
compilers supply their own run time libraries which take precedence for 
functions like printf() over the very old MSVCRT supplied with the OS, 
so doing it the ANSI way is not difficult.  I wonder if they may not now 
also use an 80 bit long double, so that "%Lf" means something different 
from "%f", and long doubles may actually be used to print numbers with 
more precision.

I understand you do not much care for the language standard's 
requirements for "%lf", but since the standard is as it is, it would be 
nice if

    gcc -std=c99

in mingw linked in a _printf() that did what the language says it should 
do, rather than what MS compilers did long ago (or still do, for all I 
know).  More power to you if you also want to implement

    gcc -std=MSDN

or something like that, to match the (old?) MS requirements.


David Mathog
Manager, Sequence Analysis Facility, Biology Division, Caltech

Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
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