c - snprintf not working as expected with avr-gcc -
during debugging session, found out snprintf not working expected when comiling code avr-gcc. example code should convert floating point value 3999.9f character representation.
here minimal test case:
    int testsnprintf(void)     {        const float inputvalue = 3999.9f;        /* print fixed width of 6 characters (5 numbers , 1 dot).        buffer must have length of 7, because snprintf appends '\0' @ 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;    } compling example code avr-gcc , running atmel studio 7 gives return value of -2. means snprintf not working.
what if have have tried far?
- i tested code on 32 , 64 linux , works expected (testsnprintf return value 0).
- i tested code visual studio 2015 , worked expected (testsnprintf return 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 performed on device using jtag interface. tried simulator well, same result. 
- no compiler optimization activated. code compiled , debugged -o0.
here screenshot debugging session, demonstrates return value -2.
this demonstrates buf in scope during debugging: 
question
what doing wrong?
solution
first of thank help! pointed out @manilo following linker options missing:
-wl,-u,vfprintf -lprintf_flt -lm 
there 3 different implementations of printf() (and friends). default doesn't implement float output.
snprintf won't work without linking libprintf_flt.a (-lprintf_flt) , libm.a (-lm).
also, according documentation, have add 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 sequence of linker flags important: -wl,-u,vfprintf -lprintf_flt -lm

Comments
Post a Comment