2017-01-31 8 views
6

साधारण मामलों में गतिशील शाखा (वर्चुअल कॉल) देखने के लिए दृश्य सी ++ (वीएस2017 आरसी) द्वारा उत्पन्न कोड को देखते समय मैं बहुत हैरान था।दृश्य सी ++: स्पष्ट मामलों में कोई devirtualization?

struct Base 
{ 
    virtual void foo() = 0; 
}; 

struct Impl : Base 
{ 
void foo() override; 
}; 

Impl g_impl; 
void globalCall() 
{ 
    g_impl.foo(); 
} 

void localCall() 
{ 
    Impl i; 
    i.foo(); 
} 

void tempCall() 
{ 
    Impl().foo(); // dynamic branching generated! 
} 

struct Class 
{ 
    void memberCall(); 
    Impl impl; 
}; 

void Class::memberCall() 
{ 
    impl.foo(); // dynamic branching generated! 
} 

संकलक एक्सप्लोरर लिंक:

तो मैं संकलक एक्सप्लोरर के साथ निम्नलिखित कोड की कोशिश की https://godbolt.org/g/RmUku2

अस्थायी और सदस्य मामलों के साथ

, ऐसा लगता है कोई devirtualization की तरह होता है। तो क्या यह कार्यान्वयन के मुद्दे की एक कंपाइलर गुणवत्ता है, या ऐसे परिणाम के लिए तकनीकी वैध कारण हैं?

+1

क्या आपने 'अंतिम' जोड़ने का प्रयास किया था? – Yakk

उत्तर

1

बस devirtualization के लिए मामलों को याद किया। यह पहले संस्करण के बाद से ऐसा रहा है जिसमें devirtualization का समर्थन किया गया था, अर्थात् वीएस 2013. अन्य कंपाइलर्स जीसीसी, आईसीसी, और क्लैंग सभी मामलों में devirtualization प्रदर्शन करते हैं। सामान्य रूप से, अनुवांशिक रूप से devirtualization करने के लिए संकलक पर भरोसा करने के बजाय final स्पष्ट रूप से निर्दिष्ट करना बेहतर है। Impl.foo को final के साथ चिह्नित करने से सभी मामलों में अनुकूलन सक्षम हो जाता है।

संबंधित मुद्दे