I'm trying to write custom printf function.
void debug_print(const char *fmt, ...)
{
const char *p;
va_list argp;
int i;
double f;
char *s;
char fmtbuf[80];
va_start(argp, fmt);
for(p = fmt; *p != '\0'; p++)
{
if(*p != '%')
{
uart_putchar(*p);
continue;
}
switch(*++p)
{
case 'c':
...
break;
case 'f':
f = va_arg(argp, float); // ??????
s = dtostrf(f, 10, 6, fmtbuf);
uart_puts(s);
break;
...
// then in the main part of the program
debug_print("%f", 123.456);
When program comes to f = va_arg(argp, float) it never returns from that line. If I change it to f = va_arg(argp, double) it returns 0.
Tried both on device(ATMega328P) and Atmel Studio 6 simulator, same result.
Sounds like something to do with linker options?
UPDATE:
Now just need to find out why va_arg(argp, double)
returns 0.
When you pass a float
in a variable argument list, it's implicitly promoted to a double
by the compiler. So, you'll have to use va_arg(argp, double)
to fetch it from the variable argument list.
When you do try to fetch the argument as a float
, then
type
is not compatible with the type of the actual next argument (as promoted according to the default argument promotions) [and] the behavior is undefined
(Standard §7.16.1.1, The va_arg
macro. Per §6.2.7, float
and double
are not compatible.)