1

What are some legitimate and/or interesting uses for performing pointer-arithmetic on C++'s "this" pointer, if any?

Just to make SE pleased with the length of this question, I'll include some relevant code.

class Foo
{
public:
    Foo(bool terminate = false)
        : _data(terminate ? -1 : 0)
    {}

    void Bar(void)
    {
        if (_data >= 0)
        {
            _data++;
            this[1].Bar();
        }
    }

private:
    int _data;
};

void main()
{
    std::vector<Foo> vec;
    vec.push_back(Foo());
    vec.push_back(Foo());
    vec.push_back(Foo());
    vec.push_back(Foo());
    vec.push_back(Foo(true));

    vec[2].Bar();
}
Whaa
  • 109
  • 6
  • 6
    There is no legitimate reason to do this because an object should not be aware that it is a member of a contiguous array (which this assumes). And your code is infinitely recursive. – Joseph Mansfield Jan 07 '15 at 15:33
  • 5
    I don't think length is going to be the source of displeasure in this question. – Scott Hunter Jan 07 '15 at 15:33
  • 1
    Stack overflow is not "ask a programmer anything". This isn't nam, there are rules here. – Yakk - Adam Nevraumont Jan 07 '15 at 15:37
  • Please notice that nowhere does the question ask if this is a good idea generally. It obviously isn't. – Whaa Jan 07 '15 at 15:53
  • 2
    There is one good use case when you want to use this[1]. Sometimes you want a pointer to the end of the class (to test buffer overrun on its private variable). You typically do (char*)this + sizeof(*this). However in some cases this will yield a wrong result (if the size of the class is changed during compilation). In that case this[1] might help you. Usually class is defined once and should not change during compilation. But if you include a legacy old .h files that have #pragma pack(push, 1) in them (were popular in 1990-2000 years to reduce memory usage) than this[1] comes in handy. – DanielHsH Jan 07 '15 at 20:19

2 Answers2

5

Short answer: don't.

Of course, you do all sorts of black magic with this, e.g. access previous or next array elements like you've shown, access a private member of a base class via pointer offset, or get a 'unique' ID of the object from its memory location, as long as it's never moved. But all of this is very likely to backfire at some time, and for everything I can think of there is a safer solution.

One legitimate use I can think of is alignment checking. Say you have a float4 class that requires 16-byte alignment, you could put an assertion in the constructor that guarantees that (((uintptr_t)(const void *)(this)) % 16 == 0).

Community
  • 1
  • 1
Daerst
  • 954
  • 7
  • 24
0

It's legal, but as the comments have been telling you, it is terrible style.

You shouldn't do this except if you are a toolchain developer writing conformance tests.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720