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

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

  •  19-07-2023
  •  | 
  •  

Question

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;
}
Était-ce utile?

La solution

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.

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top