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