Access to object's fields by using pointer arithmetic

Normally a method uses its object's field by using their name. It's presented below, where we want to get value of description field from getDescription method.

class Car {
    std::string getDescription() {
        return description; // <- we return value of this field
    }

    std::string description;
};

The same result can be obtained by using a bit of magic with this, pointers and casting:

#include <iostream>

class Car {
public:
    Car (int _weight, int _maxSpeed, std::string _description) :
        weight(_weight), maxSpeed(_maxSpeed), description(_description) {
    }
    std::string getDescription() {
        return description;
    }
    std::string getDescriptionUsingThisKeyword() {
        return *((std::string*)((int*)this + 2));
    } 
private:
    int weight, maxSpeed;
    std::string description;
};

int main() {
    Car myCar(200, 200, "my best car ever");
    std::cout << myCar.getDescription() << std::endl;
    std::cout << myCar.getDescriptionUsingThisKeyword() << std::endl;
}

Output:

bash-3.2$ ./a.out 
my best car ever
my best car ever

It's error-prone, e.g. when someone changes order of fields in the class. I think, that it's cool but I wouldn't like to see this in a real code :)

2 comments:

  1. it can be unsafe. as i undestood 2 integers take 2 bytes and follow by description. what if another compiler will set more space for int? maybe it is better to use "2*sizeof(int)" instead of "2", but i can be wrong, of course ;)

    ReplyDelete
  2. Hi Alex,

    that would be some improvement, but I think, that this code can't be really fixed. It will always be vulnerable to changing order of fields in class and will fail silently in this case (but will compile and probably won't crash, just will work incorrectly).

    regards,
    Robert

    ReplyDelete