2017-08-23 102 views
3

我用簡單的語言讀到,如果C++編譯器可以證明變量是某種類型的,它可以內聯虛函數。爲什麼不能做到這一點在這種情況下(與MSVC 2017年進行測試,鐺4.0,GCC 7.2和ICC 17):爲什麼不能將這種虛擬方法內聯?

#include <iostream> 

class Callable { 
public: 
    virtual int sq(int n) const; 
}; 

class Square : public Callable { 
public: 
    inline int sq(int n) const override final { 
     return n*n; 
    } 
}; 

class Call { 
public:  
    const Callable caller; 
}; 

class Methods { 
public: 
    constexpr static const Call c {Square()}; 
}; 

int main() { 
    using std::cout; 
    cout << Methods().c.caller.sq(5); 
} 

我注意到,鐺的優化輸出godbolt(以下鏈接)說,Callable::sq不會因爲它的定義不可用而被內聯。但是,Methods::cstaticconstCall::caller也是const。另外,Square::sqfinal。據我所知,他們不會在運行時改變方式。或者我錯過了什麼?

在另一方面,編譯器能夠內聯函數在這個版本:

#include <iostream> 

class Callable { 
public: 
    virtual int sq(int n) const; 
}; 

class Square : public Callable { 
public: 
    inline int sq(int n) const override final { 
     return n*n; 
    } 
}; 

class Call { 
public:  
    Callable const* caller; 
}; 

class Methods { 
public: 
    Call c {new Square()}; 
}; 

int main() { 
    using std::cout;  
    cout << Methods().c.caller->sq(5); 
} 

爲什麼會這樣呢? Link爲godbolt爲便於檢查。

+0

什麼是「鏗鏘的優化視圖」? – xaxxon

+0

@xaxxon我的意思是優化輸出。我會解決它。我不確定關於鏗鏘聲,特別是編譯器,但它是godbolt的一個特性。你可以在我提供的鏈接中看到它,點擊「顯示優化輸出」。它顯示了編譯器嘗試優化代碼的步驟。 –

+0

你怎麼知道叮噹不能內聯它,它不只是選擇不?你在哪裏看到它說:「Callable :: sq不會被內聯,因爲它的定義是不可用的」我沒有看到任何地方 – xaxxon

回答

0

嘗試在虛函數聲明的末尾添加{}。

virtual int sq(int n) const {}