cavravr-gccatmelatmelstudio

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:

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

Solution

  • 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