2

我正在尝试编写自定义 printf 函数。

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);

当程序到达 f = va_arg(argp, float) 时,它永远不会从该行返回。如果我将其更改为 f = va_arg(argp, double) 它返回 0。

在设备(ATMega328P)和 Atmel Studio 6 模拟器上都试过,结果相同。

听起来像是与链接器选项有关?

更新:

现在只需要找出为什么va_arg(argp, double)返回 0。

4

1 回答 1

3

当您float在变量参数列表中传递 a 时,编译器会将其隐式提升为 a double。因此,您必须使用va_arg(argp, double)它从变量参数列表中获取它。

当您尝试将参数作为 a 获取时float,则

type与实际下一个参数的类型不兼容(根据默认参数提升)[并且]行为未定义

(标准 §7.16.1.1,va_arg宏。根据 §6.2.7,floatdouble兼容。)

于 2012-11-29T13:53:09.397 回答