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