修复奇怪的“%a”格式行为与g ++ 4.9.1? [英] Fix for bizarre "%a" format behavior with g++ 4.9.1?

查看:217
本文介绍了修复奇怪的“%a”格式行为与g ++ 4.9.1?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译器:64位MinGW G ++ 4.9.1,来自Nuwen发行版,在Windows 8.1下。

代码:

  #ifdef INCLUDE_IOSTREAM 
#include< iostream>
#endif
#include< stdio.h> // :: snprintf
#include< stdlib.h> // EXIT_SUCCESS,EXIT_FAILURE
#include< stdexcept> // std :: exception
$ b $##ifdef snprintf
#error snprintf被定义为宏
#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(%.3f与%2d数字的十六进制:%s \ n,数值,精度,缓冲区);
}

auto main() - > int
{
using namespace std;
尝试
{
for(int precision = 6; precision <= 8; ++ precision)
{
test(5.0,precision);
}
test(0.0,14);
返回EXIT_SUCCESS;
}
catch(例外常量& x)
{
fprintf(stderr,!%s\,x.what());
}
return EXIT_FAILURE;






适用于Visual C ++ (但Visual C ++似乎缺少相反的转换):

 
H:\dev\test\so\0187> < b> cl / nologo- /? 2& 1 |找到/ iler ver
用于x86

的Microsoft(R)C / C ++优化编译器版本18.00.30723 H:\dev\test \so\0187> cl barx.cpp -D INCLUDE_IOSTREAM / Feb
barx.cpp

H:\dev \test\so\0187>
十六进制5.000与6位数字:0x1.400000p + 2
十六进制5.000与7位数字: 0x1.4000000p + 2
十六进制5.000 8位数字:0x1.40000000p + 2
十六进制0.000用14位数字:0x0.00000000000000p + 0

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






当<

 
H:c $ c $< iostream> \dev\test\so\0187> g ++ --version |找到++
g ++(GCC)4.9.1

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

H:\dev\test\so\0187> a
十六进制数为5.000,数字为6:0x1.400000p + 2
十六进制数为5.000,数字为7:0x1.4000000p + 2
十六进制数为5.000 8位数字:0x1.40000000p + 2
十六进制为0.000,14位:0x0.00000000000000p + 0

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






时,挂起的奇怪结果包括< iostream>

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

H:\dev\test\so\ 0187>
十六进制5.000与六位:0xa.000000p-1
十六进制5.000与七位:0xa.0000000p-1
十六进制数为5.000,8位:0x0.00000000p-33'奇怪。
^ C< i& Hang,Ctrl + C
H:\dev\test\so\0187> _

我正在寻求解决方法或解决方法。

解决方案

微软的实施有许多 printf 错误,并且这些错误会默认影响MinGW(#377 #407 ,等等)。



在所有情况下,建议似乎是 a>在预处理器中将 __ USE_MINGW_ANSI_STDIO 定义为 1 ,以使用MinGW自己的ANSI兼容实现。



据推测,Visual Studio在底层系统代码中有缺陷的内部解决方法。


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.

解决方案

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.

这篇关于修复奇怪的“%a”格式行为与g ++ 4.9.1?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆