c++ - 在 x86 32 位的静态类实例中解决这个问题

标签 c++ static x86 relative-addressing

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

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

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 计算的内存中 - 根据编译器,这可能是一个常量地址。所以在这种情况下不需要花哨的寻址模式。

关于c++ - 在 x86 32 位的静态类实例中解决这个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49270575/

相关文章:

c++ - 带有需要原始指针的 API 的 unique_ptr?

c++ - 将结构从一个进程转移到另一个进程的最佳方法?

c++ - std::mutex 是否强制缓存内聚?

c++ - 获取 const 方法的地址

java - 如何将其添加到静态方法中的数组列表中?

c++ - 为什么我的静态指针不可访问

c# - 如何从静态方法更新控件?

optimization - 哪些非局部效应可以改 rebase 本 block 的性能?

assembly - 将十进制数转换为半字节的二进制形式

assembly - VGF2P8AFFINEINVQB是最长的x86指令助记符吗?