Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. The example code should simply convert the floating point value 3999.9f into 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;
   }

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

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).
  • I tested the code with Visual Studio 2015 and it worked as expected (TestSnprintf return the value 0).
  • The content of buf is

    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. I tried the simulator as well, with the same result.

  • No compiler optimization is activated. The code is compiled and debugged with -O0.

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

enter image description here

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

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:

-Wl,-u,vfprintf -lprintf_flt -lm
like image 648
orbitcowboy Avatar asked Jun 14 '16 15:06

orbitcowboy


Video Answer


1 Answers

There are three different implementations of printf() (and friends). The default doesn't implement float output.

snprintf won't work without linking libprintf_flt.a (-lprintf_flt) and libm.a (-lm).

Also, according to the documentation, you have to add the linker options -Wl,-u,vfprintf (e.g. here).

The sequence of the linker flags is important: -Wl,-u,vfprintf -lprintf_flt -lm

like image 77
manlio Avatar answered Oct 25 '22 03:10

manlio