c++staticx86relative-addressing

Addressing this in static classes instances on x86 32-bit


If I define static instance of a class, is there optimization in compilers (particularly g++/clang) to omit base register (for thiscalls) when data members accessed directly or indirectly (I mean [base + index * scale + displacement] formula) and just use single displacement constant for all of them? All member functions may became static (in case of sole instance of the class it is reasonable).

I can't check this, because on godbolt.org compiler aggressively optimizes following code to xor eax, eax; ret:

struct A
{

    int i;
    void f()
    {
        ++i;
    }

};

static A a;

int main(int argc, char * argv[])
{
    a.i = argc;
}

Solution

  • Short answer: Maybe.

    Long answer: A modern compiler certainly has the ability to optimize away fetching the this pointer, and using complex addressing modes is definitely within the reach of all modern compilers that I'm aware of (including, but not limited to: gcc, clang and MS Visual C).

    Whether a particular compiler chooses to do so on a specific construct is down to how well the compiler "understands" the code presented to it. As you've just experienced, the compiler removes all of your code, because it doesn't actually "do" anything. You're just assigning a member of a global struct, which is never again used, so the compiler can reason that "well, you never use it again, so I won't do that". Remove static, and it's plausible that the compiler can't know that it's not used elsewhere. Or print the value of a.i, or pass it to an external function that can't be inlined, etc, etc.

    In your example, I would really just expect the compiler to store the value of argc into the address of a.i, and that can probably be done in two instructions, move argc from stack into a register, and move that register into the memory calculated for a.i - which is probably a constant address according to the compiler. So no fancy addressing modes needed in this case.