Search code examples
c++pointersdiskpointer-arithmeticreinterpret-cast

Accessing data via pointer(reinterpret cast) vs . or -> operator


What is the main aim of accessing data via a pointer address using reinterpret_cast. Is it faster, if so, how exactly?

Below a program, which prints same struct data via . operator and via pointer(reinterpret cast).

#include <iostream>
using namespace std;

struct values{
    int one;
    int two;
    char three;
    int four;
};

int main()
{
    values v { 8, 5, 'k', 653};

    // access via . (or ->) operator
    cout << v.one << endl;
    cout << v.two << endl;
    cout << v.three << endl;
    cout << v.four << endl;


    //via pointer access - how can this be beneficial?
    values* vPtr = &v;
    int* intPtr = reinterpret_cast<int*>(vPtr);
    cout << *intPtr << endl;
    intPtr++;
    cout << *intPtr << endl;
    intPtr++;
    char* charPtr = reinterpret_cast<char*>(intPtr);
    cout << *charPtr << endl;
    charPtr += 4;
    int* intPtr2 = reinterpret_cast<int*>(charPtr);
    cout << *intPtr2<< endl;

    return 0;
}

Solution

  • You can only access the first member via your so-called pointer access. This is permitted because v and v.one are pointer-interconvertible according to [basic.compound] paragraph 4:

    Two objects a and b are pointer-interconvertible if:

    • ...

    • one is a standard-layout class object and the other is the first non-static data member of that object, or, ...

    • ...

    If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_­cast.

    However, the only benefit I can see is that you can access the member even if you don't know its name (i.e. one in your example).

    Note: I believe there should be no performance gain. Otherwise, an optimizer can optimize the evaluation of v.one as if reinterpret_cast<int*>(&v) is evaluated instead with knowing they are equivalent at compile time.


    Accessing other members via pointer access in your example is undefined behavior. As @TWBennet said, one reason is that there may be paddings between adjacent members. However, even if there is no padding, intptr++ only obtains a pointer past-the-end, which will not automatically point to the member even at the same address. You can see details in that question.