在调试会话期间,我发现在使用avr-gcc编译代码时,snprintf
无法按预期工作。示例代码应该只是将浮点值3999.9f
转换为其字符表示形式。
这是一个最小的测试用例:
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;
}
使用avr-gcc编译此示例代码并使用Atmel Studio 7运行它会返回值 -2 。这意味着snprintf
无效。
到目前为止我尝试了什么:
TestSnprintf
返回值0)。TestSnprintf
返回值0)。 buf
的内容是
buf[0] = 32;
buf[1] = 32;
buf[2] = 32;
buf[3] = 32;
buf[4] = 32;
buf[5] = 63;
buf[6] = 0;
使用JTAG接口在设备上执行测试。我也尝试了模拟器,结果相同。
-O0
进行编译和调试。以下是调试会话的屏幕截图,其中显示返回值 -2 。
问题
我做错了什么?
解
首先非常感谢你的帮助! 正如@manilo所指出的,缺少以下链接器选项:
-Wl,-u,vfprintf -lprintf_flt -lm
答案 0 :(得分:10)
printf()
(和朋友)有三种不同的实现方式。默认情况下不实现浮点输出。
snprintf
(libprintf_flt.a
)和-lprintf_flt
(libm.a
), -lm
将无效。
此外,根据文档,您必须添加链接器选项-Wl,-u,vfprintf
(例如http://winavr.scienceprog.com/avr-gcc-tutorial/using-sprintf-function-for-float-numbers-in-avr-gcc.html)。
链接器标志的顺序很重要:-Wl,-u,vfprintf -lprintf_flt -lm
答案 1 :(得分:-1)
“另请注意,默认情况下,Arduino IDE不会将AVR链接器选项设置为支持xxprintf()例程中的浮点。因此,虽然这样可以在AVR版本上节省相当多的代码空间,但这意味着printf( )函数不能用于AVR上的浮点输出。默认情况下,其他处理器都包含浮动支持。“ http://playground.arduino.cc/Main/Printf