首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++编译器可以在同一个指针上优化重复的虚拟函数调用吗?

C++编译器可以在同一个指针上优化重复的虚拟函数调用吗?
EN

Stack Overflow用户
提问于 2013-02-07 17:12:56
回答 2查看 1.4K关注 0票数 16

假设我有以下代码

代码语言:javascript
运行
复制
void f(PolymorphicType *p)
{
    for (int i = 0; i < 1000; ++i)
    {
        p->virtualMethod(something);
    }
}

编译器生成的代码是否会取消引用pvtable条目( virtualMethod 1或1000次)?我正在使用微软的编译器。

编辑

这是我正在看的真实世界案例生成的程序集。line->addPoint()是虚拟关注的方法。我没有装配经验,所以我慢慢地.

代码语言:javascript
运行
复制
; 369  :        for (int i = 0; i < numPts; ++i)

    test    ebx, ebx
    je  SHORT $LN1@RDS_SCANNE
    lea edi, DWORD PTR [ecx+32]
    npad    2
$LL3@RDS_SCANNE:

; 370  :        {
; 371  :            double *pts = pPoints[i].SystemXYZ;
; 372  :            line->addPoint(pts[0], pts[1], pts[2]);

    fld QWORD PTR [edi+8]
    mov eax, DWORD PTR [esi]
    mov edx, DWORD PTR [eax+16]
    sub esp, 24                 ; 00000018H
    fstp    QWORD PTR [esp+16]
    mov ecx, esi
    fld QWORD PTR [edi]
    fstp    QWORD PTR [esp+8]
    fld QWORD PTR [edi-8]
    fstp    QWORD PTR [esp]
    call    edx
    add edi, 96                 ; 00000060H
    dec ebx
    jne SHORT $LL3@RDS_SCANNE
$LN314@RDS_SCANNE:

; 365  :        }
EN

回答 2

Stack Overflow用户

发布于 2013-02-07 17:50:12

一般来说,不,这是不可能的。这个函数可以破坏*this和放置--在这个空间中从相同的基础上派生出一些新的对象。

编辑:更简单的是,该函数只需更改p即可。编译器不可能知道谁有p的地址,除非它是有关优化单元的本地地址。

票数 6
EN

Stack Overflow用户

发布于 2013-02-07 19:04:21

一般情况下是不可能的,但是有一些特殊的情况是可以优化的,特别是程序间的分析。具有完全优化和全程序优化的VS2012编译此程序:

代码语言:javascript
运行
复制
#include <iostream>

using namespace std;

namespace {
struct A {
  virtual void foo() { cout << "A::foo\n"; }
};

struct B : public A {
  virtual void foo() { cout << "B::foo\n"; }
};

void test(A& a) {
  for (int i = 0; i < 100; ++i)
    a.foo();
}
}

int main() {
  B b;
  test(b);
}

至:

代码语言:javascript
运行
复制
01251221  mov         esi,64h  
01251226  jmp         main+10h (01251230h)  
01251228  lea         esp,[esp]  
0125122F  nop  
01251230  mov         ecx,dword ptr ds:[1253044h]  
01251236  mov         edx,12531ACh  
0125123B  call        std::operator<<<std::char_traits<char> > (012516B0h)  
01251240  dec         esi  
01251241  jne         main+10h (01251230h)  

因此,它有效地优化了循环,以便:

代码语言:javascript
运行
复制
for(int i = 0; i < 100; ++i)
  cout << "B::foo()\n";
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14756958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档