Ho scritto questo breve programma per vedere come avrebbe funzionato la virtualizzazione. Il compilatore dovrebbe essere in grado di dedurre il tipo corretto:Devirtualizzazione del compilatore, non troppo intelligente?
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
void foo() { cout << "Base::foo" << endl; }
virtual void bar() { cout << "Base::bar" << endl; }
virtual ~Base() = default;
};
class Child : public Base
{
public:
void foo() { cout << "Child::foo" << endl; }
void bar() { cout << "Child::bar" << endl; }
};
int main()
{
Base* obj = new Child;
obj->foo();
obj->bar();
delete obj;
}
compilato con -O2 -std=c++11
utilizzando gcc 5.3 e 3.7 clang via https://gcc.godbolt.org/.
quello che si rivelò è che né il compilatore è stato in grado di ottimizzare tutto - inlines gcc foo()
e fa la chiamata virtuale per bar()
mentre clang rende chiamata a foo()
e devirtualizes e inline chiamata a bar()
.
Nel frattempo, se invece mi chiamo obj->bar();
e poi obj->foo();
, i compilatori non hanno alcun problema ad ottimizzare - clang inlines entrambe le chiamate e gcc fa la chiamata normale bar()
invece di uno virtuale e inline foo()
.
Qualcuno può spiegare questo comportamento?
questa domanda è strana. a cosa dovremmo rispondere? GCC è peggio di Clang? alcuni compilatori possono capire le cose, a volte mancano. Clang è più recente ed è stato creato da zero per supportare questo tipo di ottimizzazioni. –
No, sono curioso di sapere se c'è qualcosa di speciale oltre questa ottimizzazione peggiore nel caso in cui la chiamata non virtuale sia fatta prima. Alcune ottimizzazioni sono già state eseguite che disturbano la deviazione? – cailinscath
http://hubicka.blogspot.de/2014/04/devirtualization-in-c-part-5-feedback.html fornisce interessanti informazioni di base per gcc. È un intero serio degli articoli sulla deviazione dallo sviluppatore gcc che l'ha implementato. Hai provato ad aggiungere "-fwhole-program" o "-fsuggest-final-methods" a gcc? – Jens