Snprintf does not work as expected with avr-gcc

During a debugging session, I found out that snprintf does not work as expected when compiling code using avr-gcc. The sample code should simply convert the floating point value 3999.9f to its character representation.

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

Combining this sample code with avr-gcc and running it with Atmel Studio 7 gives a return value of -2 . This means that snprintf is not working.

What if you have already tried?

  • I tested the code on Linux 32 and 64 and it works as expected (TestSnprintf returns 0).
  • I tested the code using Visual Studio 2015 and worked as expected (TestSnprintf returns 0).
  • Buf content is equal

     buf[0] = 32; buf[1] = 32; buf[2] = 32; buf[3] = 32; buf[4] = 32; buf[5] = 63; buf[6] = 0; 
  • Testing is performed on the device using the JTAG interface. I also tried a simulator with the same result.

  • Compiler optimization is not activated. Code compiled and debugged with -O0.

Here is a screenshot from a debugging session that shows that the return value is -2 .

enter image description here

This shows that during debugging buf is in scope: enter image description here

Question

What am I doing wrong?

Decision

First of all, thank you all for your help! As pointed out by @manilo, the following linker options were missing:

 -Wl,-u,vfprintf -lprintf_flt -lm 
+6
source share
2 answers

There are three different options for printf() (and friends). By default, float output is not implemented.

snprintf will not work without binding libprintf_flt.a ( -lprintf_flt ) and libm.a ( -lm ).

In addition, according to the documentation, you should add the linker options -Wl,-u,vfprintf (e.g. http://winavr.scienceprog.com/avr-gcc-tutorial/using-sprintf-function-for-float-numbers-in -avr-gcc.html ).

The importance of the linker sequence: -Wl,-u,vfprintf -lprintf_flt -lm

+9
source

"Also note that by default, the Arduino IDE does not set the AVR linker options for floating point support in xxprintf () procedures. Therefore, although it saves a lot of code on AVR assemblies, this means that printf () cannot be used for output floating point in AVR. Floating support is enabled by default for other processors. " http://playground.arduino.cc/Main/Printf

-one
source

All Articles