snprintf 无法按预期使用 avr-gcc

snprintf not working as expected with avr-gcc

在调试期间,我发现在使用 avr-gcc 编译代码时 snprintf 没有按预期工作。示例代码应该简单地将浮点值 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 '[=10=]' 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] != '[=10=]')
      {
          return -2;
      }

      return 0;
   }

   int main(void)
   {
     int retVal = TestSnprintf();
     return 0;
   }

使用 avr-gcc 编译此示例代码并使用 Atmel Studio 7 运行 编译此示例代码会得到 return 值 -2。这意味着 snprintf 不工作。

目前我尝试过的:

这是调试会话的屏幕截图,显示 return 值为 -2.

这表明 buf 在调试期间在范围内:

问题

我做错了什么?

解决方案

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

-Wl,-u,vfprintf -lprintf_flt -lm

printf()(和朋友们)有三种不同的实现方式。默认不实现float输出。

如果不链接 libprintf_flt.a (-lprintf_flt) 和 libm.a (-lm),

snprintf 将无法工作。

此外,根据文档,您必须添加链接器选项 -Wl,-u,vfprintf(例如 here)。

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

"Also note that by default the Arduino IDE does not set the AVR linker options to support floating point in the xxprintf() routines. So while that saves quite a bit of code space on the AVR builds, it means that printf() functions cannot be used for floating point output on the AVR. Floating support is included by default for the other processors." http://playground.arduino.cc/Main/Printf