https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92985
--- Comment #2 from Peter Dimov <pdimov at gmail dot com> --- Two more reformulations that activate the linear transformation are: int operator[]( std::size_t i ) const noexcept { std::ptrdiff_t offset; switch( i ) { case 0: offset = offsetof(X, x); break; case 1: offset = offsetof(X, y); break; case 2: offset = offsetof(X, z); break; default: __builtin_unreachable(); } return *(int const*)((char const*)this + offset); } (https://godbolt.org/z/cJDB_m) and int operator[]( std::size_t i ) const noexcept { int X::* p; switch( i ) { case 0: p = &X::x; break; case 1: p = &X::y; break; case 2: p = &X::z; break; default: __builtin_unreachable(); } return this->*p; } (https://godbolt.org/z/xfsKh5)