简体   繁体   English

snprintf 与 avr-gcc 无法按预期工作

[英]snprintf not working as expected with avr-gcc

During a debugging session, I found out that snprintf is not working as expected when compiling the code with avr-gcc.在调试会话期间,我发现使用 avr-gcc 编译代码时snprintf没有按预期工作。 The example code should simply convert the floating point value 3999.9f into its character representation.示例代码应该简单地将浮点值3999.9f转换为其字符表示。

Here is a minimal test case:这是一个最小的测试用例:

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

Compiling this example code with avr-gcc and running it with Atmel Studio 7 gives a return value of -2 .使用 avr-gcc 编译此示例代码并使用 Atmel Studio 7 运行它会得到-2的返回值。 This means snprintf is not working.这意味着snprintf不起作用。

What I have tried so far:到目前为止我尝试过的:

  • I tested the code on 32 and 64 bit Linux and it works as expected ( TestSnprintf return the value 0).我在 32 位和 64 位 Linux 上测试了代码,它按预期工作( TestSnprintf返回值 0)。
  • I tested the code with Visual Studio 2015 and it worked as expected ( TestSnprintf return the value 0).我使用 Visual Studio 2015 测试了代码,它按预期工作( TestSnprintf返回值 0)。
  • The content of buf is buf的内容是

    buf[0] = 32; buf[1] = 32; buf[2] = 32; buf[3] = 32; buf[4] = 32; buf[5] = 63; buf[6] = 0;
  • The testing is performed on the device using the JTAG interface.使用 JTAG 接口在设备上执行测试。 I tried the simulator as well, with the same result.我也尝试了模拟器,结果相同。

  • No compiler optimization is activated.没有激活编译器优化。 The code is compiled and debugged with -O0 .代码使用-O0编译和调试。

Here is a screenshot from the debugging session, that demonstrates that the return value is -2 .这是调试会话的屏幕截图,它表明返回值为-2

在此处输入图片说明

This demonstrates that buf is in scope during debugging:这表明buf在调试期间在范围内: 在此处输入图片说明

Question问题

What am I doing wrong?我做错了什么?

SOLUTION解决方案

First of all thank you all very much for your help!首先非常感谢大家的帮助! As pointed out by @manilo the following linker options were missing:正如@manilo 所指出的,缺少以下链接器选项:

-Wl,-u,vfprintf -lprintf_flt -lm

There are three different implementations of printf() (and friends). printf() (和朋友)有三种不同的实现。 The default doesn't implement float output.默认不实现浮点输出。

snprintf won't work without linking libprintf_flt.a ( -lprintf_flt ) and libm.a ( -lm ).如果不链接libprintf_flt.a ( -lprintf_flt ) 和libm.a ( -lm ), snprintf将无法工作。

Also, according to the documentation, you have to add the linker options -Wl,-u,vfprintf (eg here ).此外,根据文档,您必须添加链接器选项-Wl,-u,vfprintf (例如此处)。

The sequence of the linker flags is important: -Wl,-u,vfprintf -lprintf_flt -lm链接器标志的顺序很重要: -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." “还要注意,默认情况下,Arduino IDE 不会设置 AVR 链接器选项来支持 xxprintf() 例程中的浮点。因此,虽然这在 AVR 构建中节省了相当多的代码空间,但这意味着 printf() 函数不能用于 AVR 上的浮点输出。其他处理器默认包含浮点支持。” http://playground.arduino.cc/Main/Printf http://playground.arduino.cc/Main/Printf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM