使用 g++ 4.9.1 修复奇怪的“%a”格式行为?

Posted

技术标签:

【中文标题】使用 g++ 4.9.1 修复奇怪的“%a”格式行为?【英文标题】:Fix for bizarre "%a" format behavior with g++ 4.9.1? 【发布时间】:2015-01-25 12:33:00 【问题描述】:

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

代码:

#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;


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

H:\dev\test\so\0187>cl /nologo- /? 2>&1 |查找 /i "ler ver" Microsoft (R) C/C++ 优化编译器版本 18.00.30723 for x86 H:\dev\test\so\0187>cl barx.cpp -D INCLUDE_IOSTREAM /Feb 巴克斯.cpp H:\dev\test\so\0187>b 6 位十六进制 5.000:0x1.400000p+2 具有 7 位数字的十六进制 5.000:0x1.4000000p+2 十六进制 5.000 8 位:0x1.40000000p+2 14 位十六进制 0.000:0x0.00000000000000p+0 H:\dev\test\so\0187>_

&lt;iostream&gt; 包含时,也可以与 g++ 一起正常工作:

H:\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 6 位 5.000 的十六进制数:0x1.400000p+2 5.000 的十六进制,7 位数字:0x1.4000000p+2 8 位 5.000 的十六进制数:0x1.40000000p+2 14 位 0.000 的十六进制数:0x0.00000000000000p+0 H:\dev\test\so\0187>_

当包含&lt;iostream&gt; 时出现奇怪的结果并挂起

H:\dev\test\so\0187>g++ -std=c++11 -D INCLUDE_IOSTREAM barx.cpp H:\dev\test\so\0187>a 6 位 5.000 的十六进制数:0xa.000000p-1 5.000 的十六进制,7 位数字:0xa.0000000p-1 8 位 5.000 的十六进制数:0x0.00000000p-33 ← Weird. ^C ← 挂起,Ctrl+C H:\dev\test\so\0187>_

我要求修复或解决方法。

【问题讨论】:

不要在g++ 4.8.3/Cygwin中得到问题 @paxdiablo 不确定这有什么帮助,例如iostream 格式化可以通过调用 printf 在内部实现。我不同意 (4) 中的建议,只是因为 iostream 的存在并不会使它们变得更优越(与其他点中的建议不同),所以有充分的理由使用 stdio @paxdiablo: g++ 4.9.1 不支持std::hexfloat g++ 4.9.0 似乎也不错:coliru.stacked-crooked.com/a/ba3a2906585b17e4 这似乎是 MinGW 的问题,我可以使用 MinGW-g++ 4.9.0 和 4.9.1 的 x64 版本重现它 【参考方案1】:

Microsoft 的实现有许多 printf 错误,默认情况下这些错误会影响 MinGW(#377、#407 等)。

在所有情况下,建议 appears to be 在预处理器中将 __USE_MINGW_ANSI_STDIO 定义为 1,以改用 MinGW 自己的 ANSI 兼容实现。

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

【讨论】:

我想知道这是否意味着他们也会费心修复std::to_string 它仍然与__USE_MINGW_ANSI_STDIO=1 一起崩溃,但无论如何了解这点真的很有用。谢谢。 抱歉,我的意思是“挂起”。

以上是关于使用 g++ 4.9.1 修复奇怪的“%a”格式行为?的主要内容,如果未能解决你的问题,请参考以下文章

移动硬盘无法新建文件夹怎么修复?

洛谷 P1111 修复公路

luogu P1111 修复公路

洛谷 P1111 修复公路 Label:并查集

修复公路

处理奇怪格式的csv文件