在 x86 32 位上的静态类实例中解决此问题

Addressing this in static classes instances on x86 32-bit

本文关键字:实例 解决 问题 静态类 x86      更新时间:2023-10-16

如果我定义类的静态实例,编译器(特别是 g++/clang)中是否有优化,以便在直接或间接访问数据成员时省略base寄存器(对于this调用)(我的意思是公式[base + index * scale + displacement]),并且只对所有这些成员使用单个displacement常量?所有成员函数都可以变为静态(在类的唯一实例的情况下,这是合理的)。

我无法检查这一点,因为编译器 godbolt.org 积极优化以下代码以xor eax, eax; ret

struct A
{
int i;
void f()
{
++i;
}
};
static A a;
int main(int argc, char * argv[])
{
a.i = argc;
}

简短的回答:也许吧。

长答案:现代编译器当然有能力优化获取this指针,并且使用复杂的寻址模式绝对在我所知道的所有现代编译器(包括但不限于:gcc,clang和MS Visual C)的范围内。

特定编译器是否选择在特定构造上执行此操作取决于编译器对呈现给它的代码的"理解"程度。正如您刚刚经历的那样,编译器会删除您的所有代码,因为它实际上并没有"执行"任何操作。你只是在分配一个全局结构的成员,该成员永远不会再使用,所以编译器可以推理"好吧,你再也不会使用它了,所以我不会那样做"。删除static,编译器可能不知道它没有在其他地方使用。或者打印a.i的值,或者将其传递给无法内联的外部函数,等等。

在您的示例中,我真的只是希望编译器将argc的值存储到a.i的地址中,这可能可以通过两条指令来完成,argc从堆栈移动到寄存器中,然后将该寄存器移动到为a.i计算的内存中 - 根据编译器,这可能是一个常量地址。因此,在这种情况下不需要花哨的寻址模式。