指针操作导致printf以相反的顺序打印参数?

时间:2014-05-10 14:09:33

标签: c++ pointers printf

这是从虚拟机实验中删除的一小段代码。 它应该从字节缓冲区推送和弹出双打。 但是,它显示了一些非常有趣的行为......具体来说,它以某种方式使printf以相反的顺序打印其参数,至少在使用MinGW g ++ 4.8.1编译时。 这是怎么回事? O_O

#include <stdio.h>

#define STACK_BYTES (1024 * 1024 * 2)

struct VM {
    uint8_t* stack;
    uint8_t* sp;

    VM()
    {
        stack = new uint8_t[STACK_BYTES];
        sp = stack;
    }

    ~VM()
    {
        delete[] stack;
    }

    void pushv(double val)
    {
        *(double*)sp = val;
        sp += sizeof(double);
    }

    double popv()
    {
        sp -= sizeof(double);
        return *(double*)sp;
    }
};

int main()
{   
    VM vm;

    vm.pushv(666.f);
    vm.pushv(777.f);
    vm.pushv(888.f);

    printf("%f ", vm.popv());
    printf("%f ", vm.popv());
    printf("%f\n", vm.popv()); // 888.000 777.000 666.000, as expected.

    printf("SP: %d\n", (int)(vm.sp - vm.stack)); // SP: 0, as expected.

    vm.pushv(666.f);
    vm.pushv(777.f);
    vm.pushv(888.f);

    printf("%f %f %f\n", vm.popv(), vm.popv(), vm.popv()); // 666.000 777.000 888.000???

    return 0;
}

2 个答案:

答案 0 :(得分:1)

标准没有指定任何评估参数的顺序。您的代码是未指定

printf("%f %f %f\n", vm.popv(), vm.popv(), vm.popv());

可能在各种编译器实现中有不同的结果。你的第一个版本更好。

答案 1 :(得分:0)

编译器评估从最后一个传递到printf函数的参数,从最后一个接一个地将它们推入堆栈。
如果订单有问题,请使用中间变量。