snprintf与avr-gcc无法正常工作

orb*_*boy 6 c avr avr-gcc atmel atmelstudio

在调试会话期间,我发现snprintf在使用avr-gcc编译代码时无法按预期工作.示例代码应该简单地将浮点值3999.9f转换为其字符表示形式.

这是一个最小的测试用例:

    int TestSnprintf(void)
    {
       const float inputValue = 3999.9f;
       /* Print with a fixed width of 6 characters (5 numbers and 1 dot).
       The buffer must have a length of 7, because snprintf appends a '\0' at the end. */
       char buf[7U] = {0, 0, 0, 0, 0, 0, 0};
       const uint8_t bufferSize = 7U;
       if(6 != snprintf(buf, bufferSize, "%06.1f", inputValue))
       {
          return -1;
       }
       if( buf[0] != '3'
            || buf[1] != '9'
            || buf[2] != '9'
            || buf[3] != '9'
            || buf[4] != '.'
            || buf[5] != '9'
            || buf[6] != '\0')
      {
          return -2;
      }

      return 0;
   }

   int main(void)
   {
     int retVal = TestSnprintf();
     return 0;
   }
Run Code Online (Sandbox Code Playgroud)

使用avr-gcc编译此示例代码并使用Atmel Studio 7运行它会返回值-2.这意味着snprintf无法正常工作.

到目前为止我尝试了什么:

  • 我在32位和64位Linux上测试了代码,它按预期工作(TestSnprintf返回值0).
  • 我使用Visual Studio 2015测试了代码,它按预期工作(TestSnprintf返回值0).
  • 内容buf

    buf[0] = 32;    
    buf[1] = 32;    
    buf[2] = 32;    
    buf[3] = 32;    
    buf[4] = 32;    
    buf[5] = 63;    
    buf[6] = 0;
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用JTAG接口在器件上执行测试.我也尝试了模拟器,结果相同.

  • 没有激活编译器优化.代码使用编译和调试-O0.

以下是调试会话的屏幕截图,它显示返回值为-2.

在此输入图像描述

这表明buf调试期间的范围是: 在此输入图像描述

我究竟做错了什么?

首先,非常感谢大家的帮助!正如@manilo所指出的,缺少以下链接器选项:

-Wl,-u,vfprintf -lprintf_flt -lm
Run Code Online (Sandbox Code Playgroud)

man*_*lio 10

printf()(和朋友)有三种不同的实现方式.默认情况下不实现浮点输出.

snprintf没有链接libprintf_flt.a(-lprintf_flt)和libm.a(-lm)将无法工作.

此外,根据文档,您必须添加链接器选项-Wl,-u,vfprintf(例如http://winavr.scienceprog.com/avr-gcc-tutorial/using-sprintf-function-for-float-numbers-in-avr-gcc. HTML).

链接器标志的顺序很重要: -Wl,-u,vfprintf -lprintf_flt -lm