c++pointerspointer-arithmeticconst-pointer

Type conversions of a void pointer for pointer arithmetics


For using pointer arithmetics the type of a void pointer is converted multiple times.

The vector containing the data comes from an external source and returns a void pointer to access its data. Furthermore, the stride is also given by the external object and it heeds alignment requirements. To keep the example short it does not fully reflect those two facts.

// Example data from external source.
struct Data {
    float x;
    float y;

    Data() : x(5), y(8) {}
};

// Example vector from external source.
size_t elements = 3;
std::vector<Data> list;
list.resize(elements);

// Pointer conversions.
const void * voidPointer = list.data(); // The external object containing the vector returns a void pointer.
const uint8_t * countPointer = static_cast<const uint8_t*>(voidPointer);

// Pointer arithmetics.
unsigned stride = sizeof(Data); // The external object returning the stride heeds alignment requirements.
for (size_t counter = 0; counter < elements; ++counter, countPointer += stride) {
    const float * pointsToFloatX = reinterpret_cast<const float*>(countPointer);
    printf("%f, ", *pointsToFloatX); // Expecting something like 5.0000, 5.0000, 5.0000
}

The conversion to uint8_t does not affect the (float) data the pointer is pointing to since only the type of the pointer is converted?

Why const works on the countPointer though it gets incremented? Does const mean that the data the pointer points to may not be altered?

Why I have to use reinterpret_cast<const float*> instead of static_cast<const float*> to convert countPointer inside the loop?


Solution

  • The conversion to uint8_t does not affect the (float) data the pointer is pointing to since only the type of the pointer is converted?

    That's right. But when casting pointers, keep in mind that there are alignment requirements. Also, note that &list points to vector<Data>; you would use list.data() to get the Data* array.

    Why const works on the countPointer though it gets incremented? Does const mean that the data the pointer points to may not be altered?

    Yes. Write float * const to make the pointer itself constant or const float * const to get a constant pointer to constant data.

    Why I have to use reinterpret_cast<const float*> instead of static_cast<const float*> to convert countPointer inside the loop?

    Compatible types can be cast with static_cast, for others use reinterpret_cast. void* is compatible with any other. Avoid using reinterpret_cast unless you are very sure you know what you are doing.