Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fix for bizarre "%a" format behavior with g++ 4.9.1?

Compiler: 64-bit MinGW G++ 4.9.1 from the Nuwen distro, under Windows 8.1.

Code:

#ifdef INCLUDE_IOSTREAM
#   include <iostream>
#endif
#include <stdio.h>      // ::snprintf
#include <stdlib.h>     // EXIT_SUCCESS, EXIT_FAILURE
#include <stdexcept>    // std::exception

#ifdef snprintf
#   error snprintf defined as macro
#endif

#ifdef _MSC_VER
    auto const snprintf = _snprintf;
#endif

void test( double const value, int const precision)
{
    char buffer[34];
    snprintf( buffer, sizeof( buffer ), "%.*a", precision, value );
    printf( "Hex of %.3f with %2d digits: %s\n", value, precision, buffer );
}

auto main() -> int
{
    using namespace std;
    try
    {
        for( int precision = 6; precision <= 8; ++precision )
        {
            test( 5.0, precision );
        }
        test( 0.0, 14 );
        return EXIT_SUCCESS;
    }
    catch( exception const& x )
    {
        fprintf( stderr, "!%s\n", x.what() );
    }
    return EXIT_FAILURE;
}

Works fine with Visual C++ (but Visual C++ appears to lack the opposite conversion):

H:\dev\test\so\0187>cl /nologo- /? 2>&1 | find /i "ler ver"
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30723 for x86

H:\dev\test\so\0187>cl barx.cpp -D INCLUDE_IOSTREAM /Feb
barx.cpp

H:\dev\test\so\0187>b
Hex 5.000 with  6 digits: 0x1.400000p+2
Hex 5.000 with  7 digits: 0x1.4000000p+2
Hex 5.000 with  8 digits: 0x1.40000000p+2
Hex 0.000 with 14 digits: 0x0.00000000000000p+0

H:\dev\test\so\0187>_

Also works fine with g++ when <iostream> is not included:

H:\dev\test\so\0187>g++ --version | find "++"
g++ (GCC) 4.9.1

H:\dev\test\so\0187>g++ -std=c++11 barx.cpp

H:\dev\test\so\0187>a
Hex of 5.000 with  6 digits: 0x1.400000p+2
Hex of 5.000 with  7 digits: 0x1.4000000p+2
Hex of 5.000 with  8 digits: 0x1.40000000p+2
Hex of 0.000 with 14 digits: 0x0.00000000000000p+0

H:\dev\test\so\0187>_

Bizarre result w/hang when <iostream> is included:

H:\dev\test\so\0187>g++ -std=c++11 -D INCLUDE_IOSTREAM barx.cpp

H:\dev\test\so\0187>a
Hex of 5.000 with  6 digits: 0xa.000000p-1
Hex of 5.000 with  7 digits: 0xa.0000000p-1
Hex of 5.000 with  8 digits: 0x0.00000000p-33           ← Weird.
^C                                                      ← Hang, Ctrl+C
H:\dev\test\so\0187>_

I’m asking for a fix or workaround.

like image 797
Cheers and hth. - Alf Avatar asked Nov 27 '14 01:11

Cheers and hth. - Alf


1 Answers

Microsoft's implementation has a number of printf bugs, and these affect MinGW by default (#377, #407, et al).

In all cases the recommendation appears to be to define __USE_MINGW_ANSI_STDIO as 1 in the preprocessor to use MinGW's own ANSI-compliant implementation instead.

Presumably, Visual Studio has its own internal workarounds for the flaws in the underlying system code.

like image 194
Lightness Races in Orbit Avatar answered Nov 09 '22 09:11

Lightness Races in Orbit