0

I was trying to read an integer stored in a file as 4 bytes. To read it, I implemented the function readInt() which will read the next four bytes of a char array and transform it to an integer.

//The whole thing is in a class
char *content;
uint32_t index = 0;

uint32_t nextInt() {
    const uint32_t i = index;
    index += 4;
    return ((u_char) content[i]) << 24 | ((u_char) content[i + 1]) << 16 | ((u_char) content[i + 2]) << 8 |
           ((u_char) content[i + 3]);
}

I used this function lots of time without any issues until today: I found a bug: When I use the function like below, it works perfectly like I want to:

uint32_t count = nextInt();
geometry.setup(count, nextInt());

But if I change the code a little bit to make it looking like below, it just stop working.

geometry.setup(nextInt(), nextInt());

I get an out of memory exception. This exception is caused because I create an array but I get a wrong argument. Things will be better if I show you how geometry.setup() works:

void Geometry::setup(uint32_t newVertexCount, uint32_t newIndexCount) {
    std::cout << newVertexCount << std::endl;
    std::cout << newIndexCount << std::endl;

    vertexCount = newVertexCount;
    indexCount = newIndexCount;
    vertices = new Vertex[vertexCount];//out-of-memory exception here. vertexCount=1065353216
    indices = new uint16_t[indexCount];
}

In the first case, newVertexCount is 36 and newIndexCount is 24 (which are the expected results).

But in the second case, the values are 1065353216 and 1052770304. Why?

Note that count is not used anywhere else.

Any idea?

iohsfush
  • 107
  • 8
  • 2
    That is too much of a code puzzle for my taste. Could you make a [mre] to demonstrate the things you are describing? – Yunnosch Feb 14 '20 at 21:23
  • 1
    TL;DR of the dupes: You cannot depend on the side affects of function calls as parameters to a function. The ordering is unspecified. – NathanOliver Feb 14 '20 at 21:26
  • 1
    In this call `geometry.setup(nextInt(), nextInt());`, the two `nextInt()` can be called in [any order](https://en.cppreference.com/w/cpp/language/eval_order) since C++17. Pre-C++17 this caused undefined behavior. – HolyBlackCat Feb 14 '20 at 21:27
  • @HolyBlackCat But they anyway won't be executed at the same time, right? – iohsfush Feb 14 '20 at 21:28
  • In C++17 they won't. – HolyBlackCat Feb 14 '20 at 21:28

0 Answers0