#Type-punning this pointer

23 messages · Page 1 of 1 (latest)

worldly hornet
#

Hey! Is this UB? ```c++
struct A {
int a, b, c, d, e;

int& operator[](size_t index) noexcept;
}

int& A::operator[](size_t index) noexcept {
assert(index >= 0 && index < 5);

return *(reinterpret_cast<int*>(this) + index);
/*
if (index == 0) return a;
if (index == 1) return b; ...
*/

}

P.S. an std::array instead of explicit variables is better, I know. This is a watered-down example.
tranquil lanternBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

clever aspen
#

It should be UB AFAIK

worldly hornet
#

follow-up question: is any and all reinterpret_cast breaking strict aliasing UB?

west crow
#

It is UB. Pointer arithmetic is only allowed for pointers in an array. Single variables count a 1 element arrays for this rule, so &a is allowed and &a + 1 gives you a pointer 1 past the end of the element (invalid pointer). The rest is UB.

#

There are exceptions for char and its variants and std::byte.

exotic cosmos
west crow
#

I believe casting from object pointer to first element is actually valid, but I'm not entirely sure.

exotic cosmos
west crow
#

Well, that's incomplete.

#

Besides char you also have signed char and unsigned char and std::byte. I think that's all of them.

#

And I believe there is a rule that allows casting from object pointer to first member.

#

So the reinterpret_cast part is fine.

#

The + index part, however, is not.

#

Probably will work in practice anyway.

#

If you dig around you can probably find the actual rule in the standard.

exotic cosmos
worldly hornet
#

I see, thanks for the very valuable articles! Thank you for your time.

#

!solved