Pointer manipulation causing printf to print arguments in reverse order? [duplicate]

StackOverflow https://stackoverflow.com/questions/23582042

  •  19-07-2023
  •  | 
  •  

Here's a little piece of code removed from an experiment with virtual machines. It's supposed to push and pop doubles from a byte buffer. However, it displays some very interesting behavior... specifically, it somehow makes printf print its arguments in reverse order, at least when compiled with MinGW g++ 4.8.1. What's going on? 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;
}
有帮助吗?

解决方案

The standard didn't specify any order to evaluate parameters. You're code is unspecified:

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

May has different result in various compiler implementation. You're first version is better.

其他提示

The compiler evaluates the parameters to pass to the printf function from the last one, pushing them on the stack one after another from the last.
If the order is a problem, use intermediate variables.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top