在 x86 32 位的静态 类 实例中解决这个问题
Addressing this in static classes instances on x86 32-bit
如果我定义 class 的静态实例,编译器(特别是 g++/clang)是否有优化以在访问数据成员时省略 base
寄存器(对于 this
调用)直接或间接(我的意思是 [base + index * scale + displacement]
公式)并且只对所有这些使用单个 displacement
常量?所有成员函数都可能变成静态的(在 class 的唯一实例的情况下这是合理的)。
我无法检查这一点,因为在 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)。
特定编译器是否选择对特定构造执行此操作取决于编译器 "understands" 代码呈现给它的程度。正如您刚刚经历的那样,编译器删除了您的所有代码,因为它实际上 "do" 什么都没有。你只是分配了一个全局结构的成员,它再也不会被使用,所以编译器可以推断出 "well, you never use it again, so I won't do that"。去掉static
,编译器可能不知道它没有在别处使用,这似乎是合理的。或者打印a.i
的值,或者传给不能内联的外部函数等等等等
在你的例子中,我真的只是希望编译器将 argc
的值存储到 a.i
的地址中,这可能可以用两条指令完成,移动 argc
从堆栈到一个寄存器,然后将该寄存器移动到为 a.i
计算的内存中——根据编译器,这可能是一个常量地址。所以在这种情况下不需要花哨的寻址模式。
如果我定义 class 的静态实例,编译器(特别是 g++/clang)是否有优化以在访问数据成员时省略 base
寄存器(对于 this
调用)直接或间接(我的意思是 [base + index * scale + displacement]
公式)并且只对所有这些使用单个 displacement
常量?所有成员函数都可能变成静态的(在 class 的唯一实例的情况下这是合理的)。
我无法检查这一点,因为在 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)。
特定编译器是否选择对特定构造执行此操作取决于编译器 "understands" 代码呈现给它的程度。正如您刚刚经历的那样,编译器删除了您的所有代码,因为它实际上 "do" 什么都没有。你只是分配了一个全局结构的成员,它再也不会被使用,所以编译器可以推断出 "well, you never use it again, so I won't do that"。去掉static
,编译器可能不知道它没有在别处使用,这似乎是合理的。或者打印a.i
的值,或者传给不能内联的外部函数等等等等
在你的例子中,我真的只是希望编译器将 argc
的值存储到 a.i
的地址中,这可能可以用两条指令完成,移动 argc
从堆栈到一个寄存器,然后将该寄存器移动到为 a.i
计算的内存中——根据编译器,这可能是一个常量地址。所以在这种情况下不需要花哨的寻址模式。