-1

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;
}
O'Neil
  • 3,790
  • 4
  • 16
  • 30
Levi
  • 141
  • 1
  • 9
  • 6
    This is just Undefined Behavior. You are violating the Strict Aliasing rule. Also know that you should never treat data members of a class (even if trivial) as an array of any sort. – WhiZTiM Jan 05 '18 at 22:02
  • Related: https://stackoverflow.com/questions/48031228/how-does-this-implementation-of-operator-function-work – R Sahu Jan 05 '18 at 22:05
  • 2
    No, reinterpret_cast will not make your code faster. It's is just a compiler directive about how to treat the sequence of bytes. – StPiere Jan 05 '18 at 22:10
  • this link should be useful to clarify your doubt. https://stackoverflow.com/questions/573294/when-to-use-reinterpret-cast – Abhishek Ramamurthy Jan 05 '18 at 22:15
  • `reinterpret_cast` [may be slower](https://stackoverflow.com/questions/3575234/reinterpret-cast-cast-cost/3575344#3575344) – MSalters Jan 08 '18 at 00:48
  • @WhiZTiM there is no strict aliasing violation here. It's OK to access an `int` object via an `int` lvalue – M.M Jan 08 '18 at 00:56

3 Answers3

2

No it is not faster. (Although it depends on exactly what you want to do)

Modifying your example a bit

char* charPtr = reinterpret_cast<char*>(&v);

says, 'Let me treat this object as a raw array of bytes'. There are many reasons to want to do this. Many of them will be to do with copying things around via read,write,send,memcpy etc.

you can also see the inverse

values *v = reinterpret_cast<values*>(buff);

Where you have an array of bytes that you want to treat as a struct (you just did a read of something you wrote before.

Note that this is an advanced technique with many pitfalls to do with padding, byte order etc. Not a 100 level thing

pm100
  • 48,078
  • 23
  • 82
  • 145
1

What you have isn't reliable because when you increment intPtr, it advances through memory by the size of an integer (that's what you told it to point to). There is no guarantee that the fields in the struct are integer-size apart. They're not all integer-sized items, of course, and the compiler is free to add padding between fields in a struct. Incrementing a pointer doesn't try to find where the next thing actually is, it just goes by the size of what it points to. Which only works on arrays.

Reinterpret_cast mostly tells the compiler to let you do something that it knows is a bad idea. Such as trying to treat a struct as an array. It's not going to speed anything up, unless it's something you shouldn't do.

T W Bennet
  • 383
  • 1
  • 7
1

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.

Community
  • 1
  • 1
xskxzr
  • 12,442
  • 12
  • 37
  • 77